safe – a command-line password manager

I tried a number of different password managers, but liked none of them. I think it is because they impose too much structure. They want to split each piece of information into fields, typically a URL, a user name, a password and a comment. But sometimes the secret data I want to store isn't so structured. And, even if it is, I don't want to spend the time deciding which piece of information goes into which slot. I want free text that I can search with grep and not decide what field I'm searching on.

I also need a password manager with a command-line interface, because I can't always run a graphical program. Sometimes the machine I'm on doesn't run an X server, sometimes the network is too slow. But, as long as it is not too slow for ssh, a command-line program still works.

So I decided to make my own password manager. I've been using the result for about eight months now and I'm still happy with it. Which means it may be useful for others as well.

The principle is simple. All secrets are stored in a text file that is encrypted with gpg (part of GnuPG). A little program called safe helps manage this file. It allows to look up, add, delete and edit a secret.

Basically, what safe does is call gpg and grep with suitable options. In other words, it doesn't do anything complicated, it just encapsulates existing tools in an easy user interface. Which is good for two reasons: Without the easy-to-use tool, I probably wouldn't create a different password for every service and probably wouldn't use random strings either. And, secondly, it's good to know that the safety and long-term availability of my password store doesn't depend on this single program. If safe fails, I can still manage my password store ‘by hand’, just not as conveniently.

Using gpg for the encryption was an obvious choice. My mailers (mainly kmail and Apple Mail) already used GnuPG for signing and encryption of e-mail, so I already had it installed and already had a private key to encrypt things with. And gpg has the nice feature that it keeps your key in memory for a few minutes, typically 20, so if you use gpg again a few minutes later (directly, or indirectly via safe or your mailer), you don't have to type your passphrase again.

The encrypted text file can contain multiple secrets. Each secret is arbitrary text and may be more than one line. In the encrypted file however, each secret is stored as one line, so that the file works well with utilities such as grep and sort. That is done by replacing each newline by the two characters ‘\n’ and, to avoid ambiguities, each backslash by ‘\b’. Those are the only changes to the text, so even without the help of the ‘safe‘ program, the file is easy to edit, if necessary.

Here is how to use safe:

Retrieving secrets

To retrieve a secret, pass a pattern that matches any part of that secret. For example, if the store contains the secret ‘login.example.org marja17 pA55word’, a command like this could be used to find it:

safe example.org

Safe will prompt for the passphrase that unlocks the user's private key (if needed), searches the store with grep and returns the matching secret(s).

The grep options -i (case-insensitive search), -F (treat the pattern as a literal string instead of a basic regular expression) and -E (treat the pattern as an extended regular expression) are also supported. For example,

safe -i EXAMPLE.org

would find the same secret as above.

If the pattern starts with a dash, put two dashes (--) and a space in front of it. The -- signals to safe the end of the options and the start of the text or pattern.

Storing secrets

To add a secret, call safe with the -a option:

safe -a this is my secret

The argument may have to be quoted if it contains characters that are special to the shell.

Note, however, that putting a secret on the command line is unsafe. Unless you have taken special measures, the command will be stored in the command history. The command history is a file (for example, ~/.bash_history) that is readable by anybody with root access or anybody who has physical access to the hard disk.

The solution is to omit the secret:

safe -a

This causes safe to prompt for the secret, with the phrase ‘Enter data:’. It will only prompt for one line of text. If the secret consists of more than one line, use -m instead:

safe -m

safe will prompt for multiple lines, with ‘End data with ^D:’. Enter all the lines and end by typing Control-D at the start of a line.

Deleting a secret

To delete a secret, use -d:

safe -d login.example.org marja17 pA55word

The text must exactly match the secret (that is, it is not a grep pattern). It is a good idea to quote it, to avoid that the shell interprets special characters (‘?’, ‘*’, etc.).

Editing a secret

You can modify an existing secret in a text editor with the -e option. For example:

safe -e EXAMPLE.org

safe will find all matching secrets and open a text editor. Each secret ends with a line that says ‘DO NOT EDIT THIS LINE’. Don't remove that line, or safe will not be able to find the beginning and end of the text of each secret.

You can read the full manual page here.

Getting the program

You can get the program by downloading the safe-latest.tgz file. It is a compressed tar archive with three files: safe itself, which is a Bash script; safe.1, the manual page; and Makefile, which may help with installing the program and the manual: For example, to install them under your own home directory, run make install PREFIX=$HOME

Related tools

To generate random passwords, I use makepasswd.

Bert Bos
Created 26 August 2018