- General usage
- File encryption and multi-line password files
- Other sensitive data encryption
More of a prereq than a tip, install
bash-completion or whatever shell completion that pertains to you. Pass usage becomes vastly easier once all command-line arguments and password-store hierarchy conveniently expand as you type.
First, all proceeding operations impact your password store directory, this either
Initialize the main password store. This merely creates the respective folder with a
.gpg-id file containing your desired gpg key identifier.
pass init <gpg id>
pass insert ebay pass insert email/user1 pass insert email/user2
Each prompts you to enter and reenter the desired password. The first creates
ebay.gpg within your password store directory, the latter two
user2.gpg within the
-e flag to echo the entered text to your terminal in exchange for only one entry prompt.)
The flexibility of any directory hierarchy is extremely helpful for password organization and command-line auto-completion. Furthermore, pass creates all missing sub-folders to any level of depth.
pass generate -c <acct_critical> 20 pass generate -c -n <acct_non_critical> 10
The first creates a more secure, alpha-numeric and symbolic 20-character password. The second creates an alpha-numeric only password (
-n = no symbols) of 10 characters. Both copy the password to the system clipboard (
-c) rather than echo it to the terminal.
pass acct_non_critical pass -c email/user1
The first echoes the password to the terminal in plain glory. The second copies the password to the system clipboard for the default 45 seconds, this handier and far more secure.
Again, auto-completion is wonderful when entering these commands.
This opens up the password for editing within your configured text
pass edit <name>
pass cp email/user1 email/user3 pass mv user4 email/user4 pass rm old_account pass rm -r email
The first effectively copies user1.gpg to user3.gpg, both to have the same password. The second moves user4.gpg to email/user4.gpg. The third deletes old_account.gpg. The fourth recursively clears the entire email subfolder of passwords.
All of these operations you can also execute using the plain unix
cp/mv/rm on the respective files in the password store directory. There’s no other metadata to consider. The mechanism is quiet simple and transparent!
pass supports multi-line passwords, manually entered via
pass insert -m <name> or edited/appended via
pass edit <name>. With
edit you can even expand an initially single-line password file.
Following traditional usage, a multi-line password might resemble the following:
EFxlP.pAFmB$xmH7|_h4 username email street address
The default copy command
pass -c only copies the first line of such a multi-line password file, in this case the very password.
pass edit or
pass [show] enables you to edit/see the entire blob.
pass -c[num] copies the indicated line.
We can thus store any amount of data in a ‘password’ file, including entire documents.
Here we pipe a file
secret_answers.txt for encrypted storage within the password file
pass insert -m sensitive/secret_answers < secret_answers.txt # Or cat secret_answers.txt | pass insert -m sensitive/secret_answers
Better yet, to recursively encrypt an entire directory
sensitive_dir within the folder
sensitive of your password store, folder structure maintained:
for file in $(find sensitive_dir -type f); do pass insert -m "sensitive/$file" < "$file" > /dev/null done
You could also achieve the above via direct
gpg manipulation outside your password store. However, pass greatly abstracts the viewing and especially the editing of such encrypted data with the simplicity of the
pass edit command.
One might suggest an encrypted container or filesystem solutions. This is ultimately a matter of taste. For my part, I’ve never cared much for their relative complexity of implementation, configuration and management.
The amount of frequently read/written files that I consider encryption-worthy (beyond whatever security inherent to their storage medium), tends to number relatively small. I’d rather deal with the ad-hoc encryption of individual files, and pass makes this seamless.
I don’t like sensitive bits to be plain text viewable, be it strictly for my own eyes. This includes not only passwords but possibly compromising API keys or other access codes.
These often appear within command line arguments or configuration files. Here I present a few use to circumvent the issue with pass.
Cloud providers often feature HTTP based APIs requiring a key. With
curl, we might access the API as such:
curl -H "API-Key: <sensitive>" ...
I’d rather the plain key not appear, per the incorporation of this shell call to pass:
curl -H "API-Key: $(pass provider/api_key)" ...
s3cmd enables CLI access to the Amazon S3 object storage. The
$HOME/.s3cfg config annoyingly echoes the access/secret keys in plain text form:
access_key = <sensitive> secret_key = <sensitive>
Instead, we can set them to blank strings (necessary for proper functioning)
access_key = '' secret_key = ''
and setup the following alias to pass the keys on the command line, encrypted in our password store:
alias s3cmd="s3cmd --access_key="'$(pass aws/access)'" \ --secret_key="'$(pass aws/secret)'
Note above the single quotes around the invocation of
$(pass ...). This is necessary to postpone the command evaluation until execution, rather than the resulting keys appear directly in your rendered alias.
mbsync locally syncs your Imap email mailbox. I personally don’t wish to be prompted for the account password on each synchronization.
The solution either requires storing the plain text password in the
Pass directive of the
.mbsyncrc config file, or the alternative password evaluator directive as follows:
PassCmd "pass email/user1"
The identical situation presents itself in the case of msmtp, the email sending framework. To store a password in the config, we could either opt for the plain text
password <plain text>, or
passwordeval "pass email/user1"
Once again, pass to the rescue.
Questions, comments? Connect.