A `!` now means force or everything and nothing else (`:w!`, `:search!`, `:export!`, `:logout!`). A command that did a second thing behind its bang takes a word for it instead: `:space new|name|rm`, `:list name|rm`, `:task [add]|edit`, `:upload seal`, `:import zip [/]`. `:card` while reading a document makes a card about it, so `:card!` is gone. Merged: `:export` downloads what has focus, a file as it is or a document as markdown (`:download` folded in); `:share [off|new]` replaces `:unshare` and `:link`, and the list's `s` and `y` give way to it and the info sheet; `:noh` replaces `:clear`; `:vault [unlock|lock|passwd]` replaces `:unlock`, `:lock` and `:passwd`; Esc in the list puts down what `m` picked up before it closes the document, replacing `:unmark`. The old spellings run as their new lines for one release through a table in commands.ts; help and Tab leave them out, and the wiki lists them. A settings sheet (`,` or `:settings`) holds the options, the vault, the backup, the signed-in browsers, ssh keys and capture tokens. Each row runs the command a line would. Bare `:set`, `:vault`, `:backup`, `:sessions`, `:sshkey` and `:token` open it at their part. `?` shows the keys and commands to start with, flagged in the keymap and the command table; a second `?` (or `:help all`) shows all of them, and a filter always searches all of them. Help rows are keyed by key and description, as two contexts can share a label.
3.4 KiB
The vault
Some files deserve more than the login: scans of documents, contracts, health records. The vault encrypts them at rest under a password of their own. They stay unreadable to anyone without it: someone with a copy of the data directory or the Proton account the mirror writes to, and even a logged-in browser while the vault is shut.
There is no recovery. Forget the vault password and every sealed file is gone, from the server and from every backup. The password is not in
.env, not indiary.dband not in the mirror.
Using it
| command | what it does |
|---|---|
:vault |
set the password the first time (ten characters at least); afterwards, the vault in the settings sheet (,), where Enter opens or locks it |
:vault unlock / :vault lock |
open / close the vault |
:upload seal |
upload files sealed, encrypted as they stream in, so the plaintext never touches the disk |
:encrypt |
seal the file under the cursor; on a folder or space, seal it for good |
:decrypt |
take the file, or the sealed folder, back out |
:vault passwd |
change the password |
A sealed file carries a lock in the list, and the bar says vault open while it
is. While the vault is shut, Enter on a sealed file asks for the password.
Sealed folders
:encrypt on a folder or a space seals it for good: every file in it now, and
every file that lands in it later. An upload, an import, an SFTP write and a
file moved in are all sealed on the way in. While the vault is shut they are
refused rather than stored readable. Folders made inside are sealed too.
:decrypt on the folder unseals it with everything in it.
Documents are not files and stay readable. Only the bytes of files are sealed;
the names of sealed files, and the documents around them, are as readable in
diary.db as everything else.
When it closes
The vault closes itself after WORKSPACE_VAULT_IDLE_MIN minutes with nobody
using it (15 by default), on logout, and whenever the server restarts. The key
is dropped from memory then. While it is shut:
- a sealed file shows as sealed and nothing more;
- a share link never serves one, open or not;
:export!refuses.
A sealed file is served with Cache-Control: no-store, so the browser keeps no
copy once the vault shuts. A sealed file is never indexed for search.
Changing the password
:vault passwd makes a new master key as well as a new password. The old password
stops opening anything at once. Every sealed file is then sealed again under the
new key in the background while the vault is open; :vault shows how far it
has come. After that, an old copy of diary.db together with the old password
opens nothing still kept anywhere.
How it works
Argon2id turns the password into a key that seals a random master key; only that sealed copy is stored. Each file has a random key of its own, sealed under the master key in the file's header together with the file's id. Its bytes are AES-256-GCM in 64 KiB records, the last one marked as last, so a file that is swapped, cut short or changed refuses to open.
Sealing an existing file writes it again under a new id, rewrites the documents that embed it, and deletes the plaintext from the disk and from Proton Drive.
Over the SFTP mount, a key reads sealed files only once it has been
given vault access with :sshkey vault <name> on, and only while the vault is
open in a browser.