Managing secrets programmatically
Generally speaking, it’s not a great idea to store password files in plain text on your computer. However, it is often useful to be able to save and inject secrets directly into scripts, or otherwise access them from the command line. I like fish shell, so all the examples are written in its scripting language. However, they should be sufficiently simple to recreate with something widespread.
Here are two convenient options which I personally use.
Keyring
Perhaps the easiest option is to use the keyring utility, which integrates nicely with the macOS keychain. Install it with
pip install keyring
Add secrets with
keyring set <secret-name> <username>
and retrieve them with
keyring get <secret-name> <username>
Note that this prints the secret to STDOUT. To copy the output to the clipboard instead, simply pipe to pbcopy (on macOS):
keyring get <secret> <username> | pbcopy
Since keyring is also a python module, it is useful when programmatically accessing secrets from within python scripts.
Pass
Another useful option is pass: visit the page for installation instructions for your device. You need to first create a new password store with an existing GPG key:
pass init <key-id>
I’ve written a short primer on GPG here. Add secrets with
pass insert <secret-name>
and show existing secrets with
pass show <secret-name>
Pass also provides a number of additional features, such as password generation. For example,
pass generate -c <secret-name>
creates a new secret and copies the result to the clipboard. This is very useful, for example, when creating new passwords for use on webpages. See the pass webpage for more many interesting features.
One downside of pass is that the default authentication flow requires command line interaction, even when your computer is unlocked (under the hood, pass uses gpg
).
If you want to be able to access secrets without providing a password, you first need to create a GPG key with no password.
You can either use the key initialization flow directly without providing a password (run gpg --gen-key
), or generate one using the command
gpg --batch --passphrase '' --quick-gen-key <no-auth-key-id> default default
Now, choose a subfolder to encrypt using the new key:
pass init -p <no-auth-foldername> <no-auth-key-id>
and reading secrets which are stored in this subfolder will not prompt you for a password. The secrets are still encrypted, in the sense that the files themselves cannot be opened without the corresponding secret key.