Password management is becoming increasingly important. Best security practices suggest using difficult to remember passwords consisting of either long string of unconnected words or randomized alphanumeric strings. These per-password difficulties are compounded by the increasing number of services brought about by the digitization of everything. While there are certainly efforts the improve this space, they all have specific limitations and the non-emergence of a widely adopted solution tells just how significant these limitations are.
A modern password management solution must:
- Sync across multiple devices: Passwords must be available in a variety of scenarios and environments to be useful.
- Allow mutable secrets: Many services require periodic password updates, this should have first-class support.
- Secure storage and retrieval: What good are secure passwords if you can not trust the central repository to securely store them.
- Present a simple UI: No solution is viable if you can not actually find your passwords.
Stash is a password management script in my scripts repository. Aligned with my usual design goals - it presents a minimalistic, lightweight application with a simple interface, favoring simplicity over robust functionality. The basic architectural design choices may be summarized as:
- GPG encrypted password file: Data is stored in a single file, which is gpg encrypted. This means to decrypt the data you must posses (1) encrypted password file, (2) gpg private key, and (3) gpg private key password.
- Hierarchical
<key,value>
password definitions: I am a huge fan of simple<key,value>
stores. I think they provide extensibility and meld well with different use-cases. - Use commodity linux tooling: Should be deployable as a simple shell script without having to install myriad dependencies.
Usage
The script usage is quite simple. To begin we will call help
to show the usage.
hamersaw@ragnarok:~$ stash help
USAGE: stash COMMAND
COMMAND:
clip copy a key's value to the clipboard
get <key> retrieve a value for the specified key
help display this help menu
init <gpg-username> initailize the stash repository
list [subkey] find all keys containing the specified subkey
recover fix system following a failure
set <key> <value> store the value for the specified key
unset <key> remove values for the key (and all subkeys)
version display the applications version
Initializing a stash storage file can be performed by calling init
with the gpg id of the private key to use for encryption. By default the storage location is $HOME/.local/share/stash
but can be manually configured by setting the stashdir
ENV variable.
hamersaw@ragnarok:~$ stash init hamersaw@protonmail.com
We can set passwords by using the set
command. Note that the hierarchical definition uses periods as the delimiter.
hamersaw@ragnarok:~$ stash set email.google.username foo
hamersaw@ragnarok:~$ stash set email.google.password bar
hamersaw@ragnarok:~$ stash set email.protonmail.username foo
hamersaw@ragnarok:~$ stash set email.protonmail.password baz
Listing the available passwords with the list
command optionally takes a prefix argument. I often combine this with grep
to easily search my password store. For example:
hamersaw@ragnarok:~$ stash list email.protonmail
email.protonmail.password
email.protonmail.username
hamersaw@ragnarok:~$ stash list | grep protonmail
email.protonmail.password
email.protonmail.username
And calling get
rather than list will print off both the key and value for each password.
hamersaw@ragnarok:~$ stash get email.google
email.google.password bar
email.google.username foo
Using clip
uses the xclip
utility internally to copy the password value to the clipboard without printing it to the screen.
hamersaw@ragnarok:~$ stash clip email.protonmail.password
Unsetting a password can be done using the unset
command. Note that this works hierarchically, so unsetting email.google
will unset both the email.google.username
and email.google.password
keys.
hamersaw@ragnarok:~$ stash unset email.google
hamersaw@ragnarok:~$ stash list
email.protonmail.password
email.protonmail.username
And finally recover
is used during failure scenarios. Stash uses a CoW mechanism to ensure that any failure is easily recoverable.
hamersaw@ragnarok:~$ stash recover
This post is part 5 / 5 of the Script Series:
- Introduction
- A Script for Managing Dotfiles
- Due: A Kanban TODO List Script
- Scripting Your UI Color-Palette
- Password Management with Stash
11 day(s) offloaded in the 100DaysToOffload challenge.