Skip to content
install & set up
$ npm i -g sefy-cli
$ cargo install sefy

# then, once:
$ export SEFY_VAULT=~/notes.bak
$ sefy init
$ sefy add note "bank card"

An inconspicuous encrypted vault

Notes, logins, cards, ssh keys and files in one encrypted file with no magic bytes, no header and nothing to recognize. Call it notes.bak and leave it anywhere.
Terminal window
$ sefy add login mail --login someone@example.com --url https://mail.example.com
Password for this item:
added "mail" as 2
$ sefy get mail
copied password of "mail" to the clipboard; clearing in 45s
clipboard cleared

The secret went to the clipboard and came back off 45 seconds later - and only because it was still the value sitting there. Anything you copied in the meantime is left alone.

Terminal window
$ head -c 32 notes.bak | xxd
00000000: 65b0 1375 a933 361d 89e2 9338 1b8d cb76 e..u.36....8...v
00000010: 0749 7515 ad12 dd40 1c3e 3e93 9282 4b5a .Iu....@.>>...KZ

No magic bytes, no header, no extension convention. Two saves of identical content share no prefix, because the salt and nonce are fresh every time.

A file that says nothing

The whole SQLite database is sealed into one blob: salt ‖ nonce ‖ ciphertext. Nothing marks it as a secret store - not a header, not an extension, not a recognizable structure.

Notes, logins, cards, keys and files

Free-form notes, logins, cards, ssh keys, Wi-Fi networks, API tokens, bank accounts, and files kept byte for byte. Tags across all of them, and search over titles and public fields.

Nothing plaintext on disk

The decrypted database lives only in memory - SQLite is never given a path, so no page, journal or temporary file lands on disk.

Secrets leave one way

sefy get copies to the clipboard and clears it on a timer; show prints an item’s surroundings but never its secret. Printing is possible, but you have to ask.

New passwords, kept as they are made

sefy gen makes a random password, a pronounceable one or a diceware passphrase in English or Russian, says exactly how many bits it holds, and with --save stores it as a login before handing it over.

Two-factor sign-in without a second app

sefy otp makes the one-time code from the key the site showed, and stores that key in the same gesture that answers the site. sefy fill puts the login, the password and a fresh code on the clipboard in turn; --qr draws the key for a phone and wipes the screen after.

Tokens for scripts, not for files

sefy run -e TOKEN=github -- ./deploy.sh hands the secret to that one command through its environment - no .env file, no export in the history - and keeps the master password’s variable out of its reach.

You do not have to remember the title

sefy on its own opens a picker: type a few letters, press Enter. sefy open goes further and loads the site while the password waits on the clipboard.

Several machines, one vault

sefy sync moves the sealed file through a transport and folds what comes back in - when both sides changed an item, the other version waits in its history, nothing dropped on a timestamp. The transport never sees the password or an item.

Every value keeps its past

An edit keeps what it replaced. sefy history shows how each version differs from now without printing a secret, and sefy restore mail 2 --field password brings back the password a site never accepted the change of.

Never a trap

sefy import brings in what KeePass, Bitwarden or a browser exported, earlier passwords included. sefy export writes it all back out as KeePass XML, CSV or sefy JSON - after making you acknowledge exactly what that file is.

Honest about limits

Inconspicuous, not deniable. It hides from a passing glance and a cloud scanner, not from a forensic examiner or from anyone who can compel a password.