Pass.jl

Pass is a Julia interface to the unix pass command. This package provides PassStore, a read-only Dict-like object inspired by Base.EnvDict.

Installation

Pass.jl can be installed using Pkg.

pkg> add https://github.com/kylesjohnston/Pass.jl#v0.1.3

Requirements

Installation of Pass.jl does not attempt to install pass (or gpg) on your system.

  • The pass command must be installed on your system and available as pass.
  • Your password store must be initialized (i.e.: pass init).
  • Passwords must be stored using standard pass commands (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_key
Warning

Running 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-KEY

From Julia, Pass.jl provides access to the same information.

using Pass
store = PassStore()  # default `pass` location
api_key = store["service/api_key"]  # "EXAMPLE-API-KEY"
Tip

For ease of use, you may want to add your default PassStore to startup.jl.

using Pass
const PASS = PassStore()

PASS can be used just like ENV to retrieve secrets.

api_key = PASS["service/api_key"]

Pass.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 with key (throws KeyError if not found)
  • get(store, key, default) - retrieves secret, returning default if key not found
  • haskey(store, key) - checks for a secret for key

API

Pass.PassStoreType
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. If nothing, 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 the pass command is not available
  • ArgumentError: If the specified directory doesn't exist or isn't initialized
source
Pass.PassModule

Provides PassStore, a Dict-like interface to the unix pass command

source

Setup

Danger

Pass.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.

Approximate steps:

  1. Generate a new gpg key gpg --full-generate-key
  2. Show the id for the generated key gpg --list-keys --keyid-format LONG
  3. Initialize the password store pass init <KEYID>
  4. Insert a secret pass insert <path-to-secret>
  5. Retrieve the secret pass show <path-to-secret>