PassStores.jl
PassStores is a Julia interface to the unix pass command. This package provides PassStore, a read-only Dict-like object inspired by Base.EnvDict.
Installation
PassStores.jl can be installed using Pkg.
pkg> add PassStoresRequirements
Installation of PassStores.jl does not attempt to install pass (or gpg) on your system.
- The
passcommand must be installed on your system and available aspass. - Your password store must be initialized (i.e.:
pass init). - Secrets must be stored using standard
passcommands (e.g.,pass insert my-service/username)
Example Usage
As an example, assume that you've previously stored an API key for a service in the default location for pass.
$ echo 'EXAMPLE-API-KEY' | pass insert -e service/api_keyRunning the command above puts EXAMPLE-API-KEY into your history, which stores your secrets on disk in plaintext. For production use, it would be better to store the key interactively.
pass insert service/api_key
...If configured correctly, this key can be retrieved at the command line.
$ pass show service/api_key
EXAMPLE-API-KEYFrom Julia, PassStores.jl provides access to the same information.
using PassStores
store = PassStore() # default `pass` location
api_key = store["service/api_key"] # "EXAMPLE-API-KEY"For ease of use, you may want to add your default PassStore to startup.jl.
using PassStores
const PASS = PassStore()PASS can be used just like ENV to retrieve secrets.
api_key = PASS["service/api_key"]PassStores.jl does not cache or store any of the values, for both simplicity and security. Secrets are retrieved directly from the pass command. A KeyError is thrown when accessing a non-existent password entry. Other process-related errors are re-thrown.
Methods
store[key]- retrieves secret withkey(throwsKeyErrorif not found)get(store, key, default)- retrieves secret, returningdefaultifkeynot foundhaskey(store, key)- checks for a secret forkey
API
PassStores.PassStore — Type
PassStore(dir=nothing)A password store interface that provides dictionary-like access to the pass command-line password manager.
Arguments
dir::Union{String,Nothing}: The password store directory path. Ifnothing, uses the default store location (~/.password-store).
Examples
# Use default password store
store = PassStore()
# Use custom password store directory
store = PassStore("/path/to/my/store")
# Retrieve passwords
password = store["service/password"]Throws
SystemError: If thepasscommand is not availableArgumentError: If the specified directory doesn't exist or isn't initialized
Setup
PassStores.jl is only as secure as your pass configuration. It is your responsibility to manage that configuration.
The intructions here are meant to serve as a starting point for moving away from plaintext credential storage. Review man gpg and man pass to learn about the options that are right for you.
Note that the example configuration in the unit tests are only intended for testing purposes.
If you do not already use pass, here are the basic steps to use PassStores.jl:
- Generate a new gpg key
gpg --full-generate-key - Show the id for the generated key
gpg --list-keys --keyid-format LONG - Initialize the password store
pass init <KEYID> - Insert a secret
pass insert <path-to-secret> - Retrieve the secret
pass show <path-to-secret>
Assuming you were able to retrieve the stored secret at the command line, you should be able to retrieve it with store[<path-to-secret>].