What Keep protects against, and what it does not
Keep encrypts your papers, passwords and codes on your own device before anything is stored. That stops a long list of things. It cannot stop everything, and a security product that does not say where it stops is asking to be trusted further than it should be. This page says both, in plain words. Where it and Keep’s own page ever disagree, this page is the careful one.
What it protects against
- Somebody who gets the stored files. A stolen laptop, a copy of the disk, a backup, the
.okeepfile in your cloud drive, a sync company: each holds only encrypted files. Opening them needs your passphrase or your recovery key. The passphrase is stretched with Argon2id, which makes every guess cost 64 MiB of memory and three passes (about a third of a second on the computer Keep was tested on), so trying a list of likely passphrases is slow. How slow is up to your passphrase: four or more unrelated words is out of reach of guessing; a single word or a pattern is not. - Us, and any server. There is no Keep server and no account. OBSCURA never holds a copy of your Keep, your passphrase or your recovery key, so there is nothing for us to lose in a breach, nothing to hand over, and nothing to read. The other side of that is below: nobody can reset your passphrase either.
- A file changed behind your back. Every stored part carries an AES-GCM tag and is bound to its own name, so a part that has been altered, damaged or swapped for another fails its check. Keep reports it and refuses to show it; it never shows you something that is not what it stored.
- Watching the network. While you use Keep, the only requests it makes are for its own code, a few libraries from this site, the word list it makes passphrases from, and, the first time you ask for a scan’s words to be read, the text reader and its English data from this site (about 4 MB, fetched; nothing of the scan is sent). The list of sites that offer two-step codes travels inside Keep’s own code, so the health check asks nothing of anybody about any site. Its page is sent with a security policy that lets it connect to nothing but this site, and the browser enforces that. The one exception you can choose is the breach check, which sends the first five characters of a password’s SHA-1 hash, a prefix shared by hundreds of unrelated passwords, through this site to Have I Been Pwned. The password and its full hash are never sent. /verify shows how to watch the traffic yourself.
- Somebody who intercepts a package. A package for one person, or one shared item, is encrypted under its own passphrase with a fresh key of its own. The file can travel by email or on a stick; without the passphrase it is noise.
- A device searched on a journey, in travel mode. Turned on before you go, travel mode leaves on the device only what you marked safe for travel, and removes the rest from the browser’s storage, encrypted copies included, and any other Keep you did not keep, once a backup of each is saved. What stays is encrypted again under a new key and a passphrase for the journey, so the recovery key and any passkey do not open it, and a part recovered later from the disk’s free space was encrypted under a key nothing on the device opens, as long as the travel passphrase is not the one you use at home. Somebody who makes you unlock it sees what travelled and nothing else.
- A share opened after its time, or twice. A shared item can be made to stop opening after a time, or to open once. Both are written into the package and bound into what its key is wrapped with, so a file with either edited out does not open at all; /keep-open and Keep refuse it once the time has passed, and /keep-open refuses a package made to open once that has already been opened in that browser.
- Somebody who photographs a QR code. An item moved to your other device by QR code is encrypted to a key the receiving device made for that one move, by ECDH on P-256 and AES-256-GCM; the codes on either screen open nothing without that device’s private half, which never leaves its tab. Six digits on both screens show that nobody put a code of their own between them.
- Another tab, another site. Browsers keep each site’s storage apart, so no other website can read Keep’s files. If Keep is opened in a second tab, the first locks itself, so two tabs never overwrite each other.
What it does not protect against
- A compromised device or browser. Malware, a keylogger, a remote-control tool, or a browser extension allowed to read the pages you visit can see what you type and what Keep shows once it is unlocked, including the passphrase as you type it. No application in a browser, Keep or any other password manager, can defend against the device it runs on. Keep the device updated, and keep browser extensions to the few you trust.
- Somebody using it while it is open. An unlocked Keep is open to whoever is at the keyboard, or looking over your shoulder. It locks after the idle time you choose (five minutes unless you change it), and when the tab has been hidden for the time you choose; lock it yourself with Lock, or the L key, when you step away.
- A forgotten passphrase with no recovery key. Nothing can open the Keep then: not you, not us, not anybody. That is what “nobody else can open it” means. Make a recovery key and print the emergency kit; the health check keeps asking until you have.
- Whoever holds your emergency kit. The kit’s recovery key, with a copy of your Keep, opens it. Keep the sheet as you would keep the deeds to a house.
- Whoever shares a Keep with you. A Keep shared with your household through a shared folder is opened by its passphrase, and everyone who has it sees and can change all of it; there are no roles. Keep what is yours alone in a Keep of your own, beside it.
- Whoever can use your passkey. If you add one, anybody who can pass your device’s fingerprint, face or PIN check, with a copy of your Keep, can open it, as you can. A passkey kept in iCloud Keychain or Google Password Manager goes wherever that account goes. Remove a passkey in Settings and it opens nothing.
- Losing the only copy. A Keep lives in this browser’s storage for this site. If the device is lost, or the site’s data is cleared, that copy goes with it. Save the Keep as a file, or keep a copy in a folder, and keep doing so; the health check counts the days.
- An older copy put back. The encryption shows that every part is one Keep wrote; it cannot show that a whole copy is the latest. Somebody able to replace your Keep file with an older complete copy would undo your changes since. They would not learn anything by it.
- What leaves Keep in the clear, by your choice. A document you save a copy of, a CSV export of your logins, a calendar file of your dates, a letter printed as a PDF, and a notification on the screen are all unencrypted, and Keep says so each time. So is the clipboard: a copied password is cleared after 30 seconds where the browser allows it, but other programs can read the clipboard in that time, and a clipboard history (Windows has one, and so do some phone keyboards) can keep a copy Keep cannot reach.
- What the encrypted files still show. The number and size of the encrypted parts, and when they change, are visible to anybody who can see the files, including a sync company. What is in them, and what they are called, is not.
- The limits of JavaScript. Keep turns the vault key into a key the browser will not let a page read back, and overwrites the bytes it came from. It cannot wipe a passphrase typed into a field, because a browser does not let a page wipe a string, and it cannot stop the operating system from writing memory to a swap file or a crash report. Locking drops every key and everything decrypted, and the browser frees the memory in its own time.
- The code you are sent. Like every web application, Keep is code this site sends to your browser, and you are trusting it to be the honest code each time. This is the largest trust Keep asks of you, and it is the same trust a downloaded password manager asks when it updates itself. Keep’s code is cached on your device after the first visit, and its page’s security policy refuses scripts, frames and connections from any other site; that guards against a mistake or a third party, not against this site itself.
- What travel mode cannot hide. It does not hide that Keep is on the device, or, from somebody who makes you unlock it and looks in Settings, that travel mode is on. A sync folder that lives on the device (Dropbox, OneDrive, iCloud Drive) still holds the whole Keep, encrypted, unless you pause it or remove it from the device before you go; Keep stops using the folder while travelling, and says so. The backup has to be somewhere the journey is not, and if you are made to give up the account it is kept in, it can be opened with your home passphrase. Browsers do not promise that a removed file is gone from the disk at once; that is why what stays is encrypted again under a new key. And if you keep the same passphrase for the journey, Keep warns you that anything recovered would open with it.
- A share after it is read. An expiry and a single opening are kept by /keep-open and by Keep, on the clock of the computer that opens the package; somebody who sets the clock back, opens it in another browser, writes a program of their own, or simply saves what they read is not stopped. A single opening is remembered in that browser’s local storage, as a short hash of the package’s id and nothing of what is in it, and clearing the site’s data forgets it. For a password, change it once it has been used.
- A package after it is opened. The person you give a package to can read everything in it and save copies. Give it only to somebody you would give the papers themselves, and send the passphrase by a different route from the file.
- A nation-state, or a court. Nothing in a browser defeats a compelled search of an unlocked device, a hardware keylogger, or an order to tell somebody your passphrase.
The details
| Part | What is used |
|---|---|
| Passphrase to key | Argon2id (version 1.3, the reference code compiled to WebAssembly by hash-wasm 4.12.0), 64 MiB, 3 passes, 1 lane, a random 16-byte salt, 32 bytes out. Where WebAssembly is switched off, PBKDF2-HMAC-SHA-256 at 600,000 iterations. The parameters are stored with the Keep, so they can be raised for new passphrases without breaking old Keeps. |
| The vault key | 32 random bytes from the browser’s generator, made once. Wrapped with AES-256-GCM under the passphrase’s key, and again under the recovery key’s, each with the Keep’s id and the slot’s name as additional data. Changing the passphrase wraps it again; nothing else is re-encrypted. |
| Recovery key | 160 random bits, stretched with HKDF-SHA-256 and a random salt (it is already random, so it needs no Argon2), written as 32 characters of Crockford base32 and a 4-character check. |
| Passkey | Optional. WebAuthn’s PRF extension, with user verification required: the authenticator’s 32 bytes for a random 32-byte salt go through HKDF-SHA-256, salted with the Keep’s id and bound to the credential, to a key that wraps the vault key with AES-256-GCM in a slot of its own. Nothing is sent to a server; there is none. Adding one asks for the passphrase, which is checked before the authenticator is asked. |
| Data | The data key comes from the vault key by HKDF-SHA-256. Every stored part (the index, each document, each thumbnail) is AES-256-GCM with a fresh random 96-bit IV and a 128-bit tag, the Keep’s id, the part’s kind and its id as additional data. |
| Storage | The browser’s private file system for this site (an IndexedDB database where a page cannot write those files). Nothing unencrypted is written to local storage, the database or the offline cache. |
| Packages | The same format, with a fresh vault key and a passphrase of their own, opened read-only at /keep-open. |
| Two-step codes | TOTP, RFC 6238, with HMAC from WebCrypto. |
| Travel mode | A new 32-byte vault key; the items that travel and their files decrypted with the old key and encrypted again with the new, AES-256-GCM as above; the header has the travel passphrase’s slot alone; every other part of the Keep, and any other Keep not kept, removed from the private file system or IndexedDB, once a backup file of each has been saved. Coming home puts the backup back over it and merges in what changed while away. |
| Shares that stop | The expiry and the single opening are in the package’s header and in the additional data its key is wrapped with (“pass|limits|until=…|once”), so a header with either changed does not unwrap. |
| Moving by QR code | ECDH on P-256 with keys made for one move; HKDF-SHA-256, salted with both public keys, to an AES-256-GCM key and, apart, a six-digit check; the item compressed and sealed, and shown as up to ten codes in turn. |
| Reading a KeePass database | KDBX 4: SHA-256 of the master password, Argon2d, Argon2id or AES-KDF as the file says (held within real costs), the header’s HMAC checked first, each block’s HMAC before its bytes are used, AES-256-CBC or ChaCha20, then the protected values revealed with ChaCha20. On the device; the file is not kept. |
Each of these is checked by the site’s own tests: published test vectors for AES-GCM, HKDF, PBKDF2, Argon2id, TOTP, ChaCha20 and AES-256; KeePass databases written by another program; travel mode’s removal looked for in the browser’s storage itself; a share with its limits edited out refused; a wrong passphrase refused; a tampered part caught; a passphrase change, a recovery key and a passkey (through a virtual authenticator) that still open the same data; and a search of every kind of browser storage, after a known secret is added, that finds no trace of it. For the site as a whole, see the threat model for every tool and /trust.