feat: organization-key (Collections) support + TUI reveal from any pane#47
Merged
Conversation
…ny pane Two fixes from daily-driving Vault against a Bitwarden-cloud account whose vault is almost entirely organization/Collection-owned. Organization-key support (the bulk of the change): - Vault decrypted only personal ciphers (and per-cipher keys under the user key); organization items — ~99% of a Collections-heavy vault — were skipped, their fields being encrypted under an org key Vault didn't hold. At unlock the agent now recovers the account RSA private key from `profile.privateKey`, RSA-OAEP-SHA1-unwraps each `profile.organizations[].key` into that org's symmetric key, and routes every cipher's decryption by `organization_id` (org key vs user key). Works online and from the offline cache. New `vault_core::org_key` module + `rsa` dependency (`ring` has no RSA decryption); justified RUSTSEC-2023-0071 ignore in deny.toml / CI. Items whose org key can't be unwrapped are still skipped; editing org items is refused for now (the write path would re-encrypt under the wrong key). TUI Space-to-reveal: - `Space` revealed a login's password from the item list but did nothing in the detail pane (logins have no per-field rows) or the folder pane. Target resolution moved into a testable `App::reveal_target`, so `Space` reveals from all three panes; cards/identities still reveal the cursor-selected masked field in the detail pane. Tests: RSA round-trip, org-cipher decrypt + edit-refusal, reveal_target across panes/types. Full `just ci` green; verified live (2274 items decrypt). Co-Authored-By: Claude Opus 4.8 (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.
Two fixes from daily-driving Vault against a Bitwarden-cloud account whose vault is ~99% organization/Collection-owned (2262 of 2274 items).
Organization-key support (the headline)
Vault decrypted only personal ciphers (and per-cipher keys under the user key); organization items were skipped — their fields are encrypted under an org key Vault didn't hold. Now, at unlock, the agent:
/syncprofile.privateKey(a type-2 EncString under the user key);profile.organizations[].key(type-4 EncString) into that org's symmetric key;organization_id— org key vs user key — viaVault::base_keys.Works online and from the offline cache (the cached
/synccarries the profile). Newvault_core::org_keymodule and a newrsadependency (ringhas no RSA decryption), with a justifiedRUSTSEC-2023-0071ignore indeny.toml+ CI (the Marvin timing attack needs a network decryption oracle; Vault unwraps org keys once, locally, at unlock).Scope: items whose org key can't be unwrapped are still skipped (logged); editing org items is refused for now — the write path would re-encrypt under the wrong key (reads/copy work). Org-aware writes are a follow-up.
TUI
Spacereveals from any paneSpacerevealed a login's password from the item list but did nothing in the detail pane (logins have no per-field rows) or the folder pane. Resolution moved into a testableApp::reveal_target: cards/identities reveal the cursor-selected masked field in the detail pane; logins/notes fall back to the primary secret; the list and folder panes reveal the selected item's primary secret — soSpaceworks from all three panes.Verification
Full
just cigreen (fmt, clippy-D warnings, test, deny, audit, reuse). New tests: RSA OAEP round-trip, org-cipher decrypt + edit-refusal,reveal_targetacross panes/types. Live-verified against the real cloud vault: login (password + TOTP), all 2274 items decrypt, org item reveal/copy, andSpacefrom all three TUI panes.🤖 Generated with Claude Code