An encrypted store for notes, credentials and files that does not announce itself: one file with no header, no extension it must keep, and no name that gives it away.
Every way of storing secrets announces itself. A .kdbx file says "password
database". age and gpg write a header. VeraCrypt wants a container and a mount.
Whoever looks at your disk, your backup drive or your cloud folder can tell
exactly where the interesting file is.
sefy is a secret store whose file looks like nothing. Notes, logins, cards,
ssh keys and files live in an encrypted SQLite database sealed into a single
blob with no magic bytes, no header and no extension convention. Call it
notes.bak, leave it among your other backups, and there is nothing to
notice.
$ 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
Threat model, honestly
- Protects against: a passing glance, a curious file listing, a cloud-side scanner looking for known formats, anyone who does not already know the file is a vault.
- Does not protect against: forensic analysis - a high-entropy headerless file is recognizable as some container to an examiner - or anyone who can compel you to give up the password.
sefy is inconspicuous, not deniable, and it will not pretend otherwise.
A day with it
Point sefy at a file. There is no default location: a vault at a predictable path would undo the whole point.
$ export SEFY_VAULT=~/backups/notes.bak
$ sefy init
Master password:
created /home/you/backups/notes.bak
Put things in - notes, logins, cards, ssh keys, and files kept byte for byte:
$ sefy add note "bank card" --text "PIN 4815" --tag money
added "bank card" as 1
$ sefy add login mail --login someone@example.com --url https://mail.example.com --tag mail
Password for this item:
added "mail" as 2
$ sefy add file ~/.ssh/id_ed25519 --tag keys
added "id_ed25519" as 3
Bare sefy opens a picker over everything in the vault:
$ sefy
? Item >
> bank card note [money]
mail login [mail]
id_ed25519 file [keys]
Take a secret out. It goes to the clipboard and is taken back off after 45 seconds - and only if the secret is still what is sitting there, so anything you copied meanwhile is left alone.
$ sefy get mail
copied password of "mail" to the clipboard; clearing in 45s
clipboard cleared
A new account needs a new password, and sefy gen makes one and keeps it in
the same breath - stored as a login, then put on the clipboard for the sign-up
form:
$ sefy gen --save forum --login someone@example.com --url https://forum.example.com
added "forum" as 4
generated 20 characters: 130 bits of entropy, strength 4/4
copied it to the clipboard; clearing in 45s
Items are addressed by title, id or text to search for, and sefy lists what
the words could mean rather than guessing. sefy open loads the site with the
password on the clipboard, sefy fill passes login, password and one-time code
one Enter at a time, sefy sync carries the vault through a transport, and
sefy status says what you hold without saying what is in it.
Every command, with its flags: the reference.
What you get
- A file that looks like nothing. No magic bytes, no header, no extension convention - salt and nonce fresh on every save, so two saves of identical content share no prefix.
- Notes, logins, cards, ssh keys, Wi-Fi networks, API tokens, bank accounts and files in one vault, tagged and searchable, with files kept byte for byte.
- Passwords made where they are kept.
sefy gendraws random characters, pronounceable ones or a diceware passphrase (English or Russian lists built in), reports its exact entropy beside an offline zxcvbn score, and can save the result as a login in the same command. - Two-factor sign-in built in.
sefy otpturns the key a site shows into the one-time code, andsefy fillhands over login, password and code one Enter at a time. - Tokens for scripts without a
.envfile.sefy run -e TOKEN=github -- ./deploy.shputs the secret in the environment of that one command - not in a file, the shell history or a process listing. - Transports, not lock-in.
sefy synccarries the vault through asefy-plugin-*executable - github and sftp ship today - and folds what comes back in without a credential ever passing through the transport. - Every value keeps its past. An edit keeps what it replaced;
sefy historyshows how each version differs without printing a secret, andsefy restorebrings one back - whole, or one field. - Merge instead of overwrite. Where two copies both changed an item, the newer is current and the other waits in its history rather than being dropped on a timestamp.
- Sync without surprises.
--dry-runnames every item a sync would touch before it touches one,SEFY_AUTO_SYNC=onsyncs after every change, a merge keeps the vault as it was beside it first, andsefy doctorchecks the vault, the transport and the clipboard on this machine. - An audit that stays home.
sefy auditnames weak, reused and year-old passwords, the card or token kept twice, and every record past or near itsexpiresdate - worked out offline, without showing a value. - A vault that is never a trap.
importreads KeePass, Bitwarden and browser exports, history included;exportwrites sefy JSON, KeePass XML or CSV - in the clear only after you say so explicitly. - An end, when one is needed.
sefy wipeoverwrites the vault, the copies beside it and any unfinished save with random bytes and deletes them, once you type the vault's name back - there is no--yes.
Install
One-line installers. Windows (PowerShell):
irm https://raw.githubusercontent.com/lacodda/sefy/main/tools/install.ps1 | iex
macOS / Linux:
|
On Windows use the PowerShell line above: install.sh carries the macOS and Linux builds only, and run from Git Bash it stops with a pointer back here.
cargo - cargo install sefy, plus cargo install sefy-plugin-github or
sefy-plugin-sftp for a transport
npm - npm install -g sefy-cli
Binary releases - grab the archive for your platform from Releases
(Windows x86_64, Linux x86_64, macOS arm64), unpack and put sefy on your
PATH.
Both installers take the newest release by default; set SEFY_VERSION to a tag
to pin one, and SEFY_INSTALL_DIR to choose where the binary lands. They also
place any transport the archive carries into sefy's plugins directory, so
sefy plugin list finds it without a second step.
Shell completions: sefy completions bash (also zsh, fish, powershell,
elvish).
Documentation
Full command reference, concepts and guides: lacodda.github.io/sefy - including how the vault works and the plugin reference for transports.
Status
v0.16.0, in daily use. The vault file format is stable at version 1 and the plugin protocol at version 1 since 0.3.0; the database schema inside the ciphertext moves between releases, and older builds keep reading a vault safely even when they cannot see everything in it - see versions and compatibility. What landed in each version: CHANGELOG.
Contributing
Building the workspace, repository layout and commit conventions: CONTRIBUTING.md.
License
MIT (c) Kirill Lakhtachev