Repository navigation
feat(web): Devices & keys, a new-key alert on sign-in, and a persistent vault - #383
Merged
Merged
Conversation
…se prompt, keys up to a year dg auth keys add --for-browser <request> registers a limited key with the master key on the terminal and prints it sealed (ECDH + HKDF + AES-256-GCM) to the one-time key the browser tab shows, so the recovery phrase never enters a web page. The web app gains Sign in -> Use dg and Renew -> With dg (the default for a key that came from dg), checks the key on chain before storing it, and can take the encryption key too. Every recovery-phrase prompt in the web app and dg shows the same fixed warning, and new browser keys can live 30 days to a year. Rust and TypeScript share the key_handoff_* and copy__* conformance vectors; forge-v2.md 6.4 documents the convention (TS-06). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Review follow-ups: dg hands over a key that landed even when the update reported an error, refuses a key for another identity (--for-identity) or one that lives past a year before signing, and no longer asks for the recovery words when the signed-in key file fails to open. The browser names the key it replaces, refuses a reply that would orphan the key it holds or drop wallet keys, keeps the dropped-encryption-key notice when the carried key cannot be stored, and suggests the right network flag. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Anyone can show a dfkr1 request, so dg says to run the command only for a Forge page you opened yourself (security review of the key handoff). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sistent vault Settings → Devices & keys lists every key on the identity as the chain has it (role, remaining budget, expiry, this browser's key), with local labels and Disable for a lost device's key, signed once by the master key. The master key, this browser's own key, the encryption key and other apps' keys are refused with the right place to go instead. Each browser keeps a snapshot of the identity's key ids; on the next sign-in or unlock a live key it did not add raises a red bar (TS-07), reusing the identity read the sign-in already makes. Keys this browser registers itself (runner, encryption) are noted as its own. The vault asks navigator.storage.persist() when it stores a key, and the page says whether the browser agreed (TS-17). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…dded Review of Devices & keys: unbounded signing keys (a wallet's) and keys bound to another app's contract group are no longer offered Disable; the master-signed disable re-checks the same rule against the identity it reads. Every key the browser holds (wallet grants, held keys) counts as its own and goes through Revoke. A wallet's encryption key, registered beside its auth key, no longer raises the new-key alert, and an acknowledgement never starts a snapshot (which would have named the master key as new). The page no longer repeats the app-wide alert. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 36 minutes. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (44)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
# Conflicts: # docs/guides/identity-and-keys.md
# Conflicts: # forge-web/components/login-modal.tsx
…encryption key stays "Revoke on chain" is now "Revoke on Platform", as the Settings button reads. The encryption key's row no longer points at a replace action the browser does not have: private repos open with it, so it is not disabled here. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
forge-v2.md: master's mirror back-links stay §6.4; key handoff becomes §6.5. rules.rs: both helpers (run_repo_name_case, run_role_oracle). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…and check the held key in the vault write The Unlock and pick-a-key paths now tell adoptHandoffKey which identity's key they replace, and a reply for another identity is refused before anything is stored. The held-key check runs again inside the vault write's IndexedDB transaction, so a key another tab stored meanwhile aborts the write instead of being overwritten. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…d renewal commitKey passes VaultChangedError through, so the dg handoff names the key to disable even when another tab left a renewal unfinished. The message covers a removed key as well as a stored one, and PendingRenewalError gets its doc comment back. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings #390's contract snapshot (sakura runs UPDATE-1) and the latest master; conflicts resolved keeping both sides. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
limited-key.ts keeps the key lifetimes; its prefix-only shortId gives way to master's 7…5 shortId from lib/utils (#368). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Stacked on #375 (the dg → browser key handoff). Until #375 merges, its three commits show here too. This PR's own changes are 60e5ba4 and b7e48e9.
What
E6 Keys, devices, recovery, part 2 of 3 (trust and safety TS-07 and TS-17).
/settings/keys/). It lists every key on the identity as Platform has it: what each key is for (master, a Forge key with a budget and an expiry, a key for one Forge contract, an unbounded signing key, encryption, transfer, another app's), the budget left (keysRemainingBudgets), the expiry, and the keys this browser holds. You can give keys local names ("work laptop"); names stay in localStorage. Disable turns off a lost device's key with one master-key update. The identity file or recovery phrase is used once and not stored, and the update costs about 0.00002 DASH.dg auth keys disable <id> --force).storeInVaultasks fornavigator.storage.persist(). The page shows whether the browser agreed and lets you ask again.docs/guides/identity-and-keys.mdgains a Devices & keys section, and the lost-laptop steps point to it.Verification
tsc,eslint,vitest: 5675 tests pass. One Argon2 test inkey-safety.test.tstimed out at 60 s with the machine at load average 250; it passes in the earlier full run and is untouched here.Live on devnet sakura, using a static build served locally and
dgon the same identity (/tmp/claude-501/e6/devices-live.mjs):#24 (high signing key).dg auth keys listshows#24 … DISABLED.may-clear, since headless Chromium refuses persistence.Screenshots:
/Users/pasta/workspace/dash-forge-qa/evidence/p0/keys-devices/pr2-*.png(alert, page, disable dialog, after disable, 390 px dark).Review: a
/code-review highpass produced 10 findings. These are fixed in b7e48e9:Not changed: three versions of the master-signed disable remain (merging them is a refactor for a later PR), and the alert does not sync across tabs (another tab updates on its next unlock). A security review of the diff found nothing at high confidence.
🤖 Generated with Claude Code