[DEPRECATED] Simple local encrypted credential management with GPG 🔐
Simple encrypted credential management with GPG.
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?
Tested on Mac OSX 10.11 with
gpg2installed from homebrew, but should work on most platforms with the above requirements.
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:
brew install gpg2 gpg-agent
gpg2 --gen-keyto generate a new keypair if you don't already have one.
brew uninstall creds
make install: Run
$ creds -h usage: creds [-h|--help] [-v|--version] [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
credsreads configuration from
CREDS_DIR="$HOME/Dropbox/creds" [email protected]
CREDS_DIR: A directory where encrypted credentials files will be stored.
GPG_KEY: The GPG key to use for encrypting credentials. Use
gpg -Kto list keys.
GPG_BIN: Path to GPG bin to use. If not set,
credswill look for
gpgin the path, preferring
editcommand will create a new credential store if one does not exist yet.
The format of credential stores is single line
KEY=valenvironment variable style lines. All other lines will be ignored when using the
$ creds edit aws-work
< .. $EDITOR launches .. > AWS_ACCESS_KEY_ID=foo AWS_SECRET_ACCESS_KEY=bar
$ creds list Credential storage dir: /Users/joe/Dropbox/creds - aws-work - misc - digitalocean
setcommand to print the contents of a credential store.
Usually you will wrap this with
evalto 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
export VARcommands generated by
creds setwill be prefixed with a single whitespace character. If you're using zsh or bash as your shell and
HISTCONTROL=env var contains
ignorespacethis 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.
runcommand 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.
unsetcommand to unset the credentials. This should also be used with
$ creds unset aws-work unset AWS_ACCESS_KEY_ID
$ eval $(creds unset aws-work)
$ cat ./circleci.keys CIRCLE_TOKEN=foo
$ creds import ./circleci.keys Encrypting './circleci.keys' to '/Users/joe/Dropbox/creds/circleci.keys.gpg'
creds is a great companion to direnv.
Place one or more eval statements in your
$ 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.
If you see an error such as the following (ambiguous) error during
gpg: [stdin]: encryption failed: Unusable public keytry using
gpg2 --edit-key for GPG 2.1+) and marking the key as "ultimately trusted".
You may use variables in assignment for other variables in a cred set but you will need to enclose the eval statement with double quotes, example:
# 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
brew install bats)
brew install shellcheck)
make helpto get a list of tasks.
keybasecommands too? but don't introduce a dependency on keybase.
joe miller, 2016