joemiller / creds

[DEPRECATED] Simple local encrypted credential management with GPG 🔐
Apache License 2.0
125 stars 0 forks source link

creds

Circle CI

Simple encrypted credential management with GPG.

Rationale

I have a lot of different sensitive environment variables to juggle. API keys, tokens, usernames, passwords, etc. I had been using simple shell scripts to set environment variables when needed, eg:

$ cat ~/Dropbox/creds/aws-work.sh
export AWS_ACCESS_KEY_ID=foo
export AWS_SECRET_ACCESS_KEY=bar

$ source ~/Dropbox/creds/aws-work.sh
$ echo $AWS_ACCESS_KEY_ID
foo

$ s3cmd ...

But I don't like storing these in plaintext on Dropbox.

Thus, how about a simple way to encrypt/decrypt these as needed with GPG?

Requirements

Tested on Mac OSX 10.11 with gpg2 installed from homebrew, but should work on most platforms with the above requirements.

Install

Several options for installation, in order of recommendation:

$ brew install joemiller/taps/creds
$ brew install joemiller/taps/creds --HEAD
$ git clone https://github.com/joemiller/creds.git
$ cd creds ; make install
$ curl https://raw.githubusercontent.com/joemiller/creds/master/creds >./creds
$ chmod +x ./creds

If you're on OSX you may need to install GPG and create a keypair. You have a few options:

Run gpg2 --gen-key to generate a new keypair if you don't already have one.

Uninstall

Usage

$ creds -h
usage: creds [-h|--help] [-v|--version] <subcommand> [arguments]

Simple encrypted credential file management with GPG.

The most commonly used subcommands are:

  list                  list available credential stores
  edit                  edit a credential store
  import                import an existing file into a new credential store
  set                   display commands to set credentials from a credential store
  unset                 display commands to unset credentials from a credential store

Configuration

creds reads configuration from ~/.credsrc file, eg:

CREDS_DIR="$HOME/Dropbox/creds"
GPG_KEY=joeym@joeym.net

Required variables:

Optional variables:

Creating a new credential store / Editing existing credential store

The edit command will create a new credential store if one does not exist yet.

The format of credential stores is single line KEY=val environment variable style lines. All other lines will be ignored when using the set and unset commands.

$ creds edit aws-work

< .. $EDITOR launches .. >
AWS_ACCESS_KEY_ID=foo
AWS_SECRET_ACCESS_KEY=bar

Listing credential stores

$ creds list
Credential storage dir: /Users/joe/Dropbox/creds
- aws-work
- misc
- digitalocean

Setting/Loading

Use the set command to print the contents of a credential store.

Usually you will wrap this with eval to set the credentials in your shell's environment.

$ creds set aws-work
 export AWS_ACCESS_KEY_ID=foo
 export AWS_SECRET_ACCESS_KEY=bar

You can then copy and paste to set these vars in your current shell or do it in one comand:

$ eval "$(creds set aws-work)"
$ echo $AWS_ACCESS_KEY_ID
foo

The export VAR commands generated by creds set will be prefixed with a single whitespace character. If you're using zsh or bash as your shell and HISTCONTROL= env var contains ignorespace this will prevent the export statements (and your secrets) from being stored in the command history. This is the default setting in bash and zsh so it's probably already set correctly.

Running a command with environment vars from a credential store

Use the run command to load environment vars from a credential store and execute a command with that environment.

Environment vars are added to the current environment so existing vars will also be available to the command.

$ creds run aws-work env | grep AWS
AWS_ACCESS_KEY_ID=foo
AWS_SECRET_ACCESS_KEY=bar

$ creds run aws-work s3cmd ls s3://some-bucket

Similar to, and inspired by, the excellent envchain util.

Unsetting

Use the unset command to unset the credentials. This should also be used with eval.

$ creds unset aws-work
unset AWS_ACCESS_KEY_ID

$ eval $(creds unset aws-work)

Importing an existing plaintext file

$ cat ./circleci.keys
CIRCLE_TOKEN=foo

$ creds import ./circleci.keys
Encrypting './circleci.keys' to '/Users/joe/Dropbox/creds/circleci.keys.gpg'

Integration with direnv

creds is a great companion to direnv.

Place one or more eval statements in your .envrc file:

$ mkdir some-aws-project
$ echo 'eval "$(creds set aws-personal)"' >some-aws-project/.envrc

$ cd some-aws-project
direnv: loading .envrc
direnv: export +AMAZON_ACCESS_KEY_ID +AMAZON_SECRET_KEY_ID

$ echo $AMAZON_ACCESS_KEY_ID
ABCDEFGHIJKLMNOP

$ cd ..
direnv: unloading

$ echo $AMAZON_ACCESS_KEY_ID
$

direnv is able to follow all of the env vars set by creds so when you leave the directory they will be automatically unloaded.

Troubleshooting

# creds edit foo
AWS_ACCESS_KEY_ID=ABCDEFGHIJKLMNOP
AMAZON_KEY_ID=$AWS_ACCESS_KEY_ID

$ eval $(creds set foo)
$ env | grep KEY_ID
AWS_ACCESS_KEY_ID=ABCDEFGHIJKLMNOP
AMAZON_KEY_ID=

$ eval "$(creds set foo)"
$ env | grep KEY_ID
AWS_ACCESS_KEY_ID=ABCDEFGHIJKLMNOP
AMAZON_KEY_ID=ABCDEFGHIJKLMNOP

Developing & Testing

Requirements:

Run make help to get a list of tasks.

TODO

Author

joe miller, 2016