Wallet password protection - #764
Conversation
Design for issue xch-dev#206: opt-in per-operation password protection for wallet secret access, transaction signing, and hardened key generation. Includes biometric convenience layer design. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
10-task plan covering keychain core changes, API layer modifications, backend endpoint threading, integration tests, and Tauri/frontend skeleton. Includes bincode backward compatibility handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add password_protected bool field to the Secret variant of KeyData, with LegacyKeyData enum and backward-compatible bincode deserialization in from_bytes(). Update all construction sites to set the flag based on whether a non-empty password was provided. Add is_password_protected() accessor to Keychain. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add change_password() method to Keychain that decrypts with the old password and re-encrypts with a new one, updating the password_protected flag. Add KeyNotFound and NoSecretKey error variants. Include tests for password changing, wrong password rejection, public key rejection, flag-on-import behavior, serialization roundtrip, and legacy format backward compatibility. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add password parameter to sign(), transact(), and transact_with() and thread it from every endpoint request struct through to the keychain. Add change_password endpoint and populate has_password on KeyInfo. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace two-step promptIfEnabled + requestPassword auth with unified requestPassword returning string | null | undefined, where undefined means cancelled. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…bels Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Biometric authentication is a global setting (not per-wallet), so it belongs in the Preferences section of GlobalSettings rather than the per-wallet Security section. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code reviewFound 2 issues:
sage/src/contexts/PasswordContext.tsx Lines 127 to 133 in 815e594
sage/src/components/WalletCard.tsx Lines 81 to 92 in 815e594 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
1. Biometric unlock now works across multiple operations. The skip flag is cleared at the start of requestPassword when the previous keychain password was accepted (i.e., we're called again without a manual dialog entry in between). 2. Delete confirmation dialog now closes when the password prompt is cancelled, matching the Details dialog behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@Hadamcik i merged 0.13 (ie main) into this PR. I'm not sure how (or if) key password protection interacts with apps or should interact with apps. Basically pre-apps, keys are encrypted at rest with a user secret and any operation that requires the keys, like singing, needs that password to retrieve the keys. Right now any app invocation back to sage that needs the keys will fail as it will have |
|
Any app action can be gated by user approval and you can make it also conditional so you can ask for password there and that is Sage's not App's. App doesn't ask for that password and it doesn't get it. |
fix #206