Skip to content

Commands

Every command that touches items works on one vault file, asks for one master password, and does one thing to the items inside it. plugin and completions are the exceptions: they report on the installation itself and need neither a vault nor a password. So is gen, until it is asked to keep what it made.

With no command at all, sefy opens a picker over the vault: type a few letters, see what matches, press Enter to show the item.

Terminal window
$ sefy
? Item ›
❯ bank code note [money]
mail login [home, work]
example login [work]

The command line is exact and remembering is not — sefy get github-work only helps someone who knows the title is not github (work). This is the way in for “it is in there somewhere”.

It is offered only when there is a terminal at both ends. Run from a script it says so and stops, rather than drawing a prompt into a pipe and waiting for a keystroke that is never coming:

Terminal window
$ sefy | cat
error: sefy with no command opens an interactive picker, and this is not a terminal
list items with: sefy ls

find is the opposite choice on purpose: it always prints a listing, in a terminal and in a pipe alike, so a script and a person get the same command.

  • init — create a new vault
  • ls — list items
  • find — search items by text, kind and tags
  • show — show an item without its secret fields
  • status — what and where this vault is, without its contents
  • add — add a note, a login, a card, an ssh key, a Wi-Fi network, an API token, a bank account or a file
  • get — copy a secret to the clipboard
  • gen — generate a password or a passphrase, and keep it as a login
  • open — open an item’s site and copy its password
  • otp — copy a one-time code, store its key, or draw it for a phone
  • fill — login, password and code to the clipboard in turn
  • run — run a command with secrets in its environment
  • edit — change a title, contents or tags
  • history — earlier versions of an item’s contents, and how each differs from now
  • restore — bring an earlier version back, whole or one field
  • rm — remove an item
  • extract — write a stored file back to disk
  • tags — list the tags in use
  • export — write the contents out as sefy JSON, KeePass XML or CSV
  • import — add what sefy, KeePass, Bitwarden or a browser exported
  • merge — fold another vault file into this one
  • push — send this vault to the remote
  • pull — fetch the remote copy and fold it in
  • sync — pull, then push

sefy has no default location: pass --vault <FILE> or set SEFY_VAULT. A vault at a predictable path like ~/.sefy/vault would undo the point of a file that looks like nothing.

Terminal window
export SEFY_VAULT=~/backups/notes.bak
Variable Meaning
SEFY_VAULT Path of the vault to work on, when --vault is not given.

The password is asked for on the terminal, without echo. For scripts, --password-env <VAR> reads it from an environment variable instead.

A password cannot be passed as an argument: it would land in the shell history and in every process listing. Password variables are never fixed names either — you name them yourself and point sefy at them with --password-env, --item-password-env or --new-password-env.

The prompt talks to the terminal itself rather than to stdin, so a command whose input comes from a pipe can still ask — cat notes.txt | sefy add note draft works. With no terminal at all — a script, CI, a service — sefy refuses to prompt rather than hanging.

Wherever a command takes a <REFERENCE>, it accepts:

  1. an id — sefy get 7;
  2. an exact title, case-insensitive — sefy get bank;
  3. text to search for, matched against titles, note bodies and a record’s public fields — sefy get grocer.

An exact title always beats a substring. If more than one item still matches, sefy lists the candidates rather than guessing:

Terminal window
$ sefy get mail
error: 2 items match "mail":
3 mail — personal login
7 mail — work login
narrow the text, or use an id

0 on success, 1 on any error, 2 when the command line itself is wrong. Errors go to stderr; a wrong password and a file that is not a vault produce the same message, because an authenticated blob genuinely cannot tell the two apart.

run is the exception: it ends with the status of the command it started, and uses 125, 126 and 127 for the ways that command can fail to start at all.