Repository navigation
Travel Mode design (no code) - #9
Merged
Merged
Conversation
Travel Mode has one threat model — you are asked to unlock your password manager by somebody you cannot refuse — and one mechanism: the items are not there to show. Every other protection in this product assumes the attacker does not have you. 1Password can remove vaults from a device because its server still holds them; removal is a cache eviction against a copy held elsewhere. KeyVault has no elsewhere, which is the entire product. Built the same way here, the feature becomes "delete credentials from the only place they exist, and hope" — a data-loss bug with a switch on it. Everything in the design follows from that. Two findings from reading the code rather than assuming: - storage.js rotates the previous vault document into a second local key on every save. Removing items and saving would leave a complete copy of them in local storage, decryptable with the same master password. Any implementation that does not explicitly purge that key is a no-op wearing a switch. - chrome.storage.local is LevelDB, so a delete writes a tombstone and the old value survives until a compaction we do not control. Travel Mode protects against being asked to open the app; it does not survive a forensic image. That belongs in the UI, not only in this document. A decoy vault is rejected outright: it prepares a lie for somebody to tell under questioning, the consequences vary by jurisdiction, and a password manager should not make that decision on anyone's behalf. Recommends building it after encrypted sync, which would give it a real restore path instead of "your backup file is the only copy".
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.
Design only — nothing implemented.
The crux: 1Password can remove vaults from a device because its server still holds them. Removal there is a cache eviction against a copy held elsewhere. KeyVault has no elsewhere — that is the product. Built the same way here it becomes delete credentials from the only place they exist, and hope.
Two things found by reading the code:
storage.jsrotates the previous vault document into a second local key on every save. Removing items and saving would leave a complete copy of the removed items in local storage, openable with the same master password. Any implementation that does not purge that key is a no-op wearing a switch.chrome.storage.localis LevelDB — a delete writes a tombstone and the old value survives until a compaction we do not control. Travel Mode protects against being asked to open the app; it does not survive a forensic image. That belongs in the UI.A decoy vault is rejected outright. It prepares a lie for somebody to tell under questioning; the consequences vary by jurisdiction, and a password manager should not make that call on someone's behalf.
Recommendation: build it after encrypted sync, which gives it a real restore path instead of your backup file is the only copy.
Three open questions at the end need answering before any code.