Git what?
Git-secret
is a tool to manage API secrets in source control -- but it doesn't have to be just API keys. This git extension allows you to encrypt/decrypt any files as you push/pull from source control. This guide should walk you through:
- Why
git-secret
? What are the advantages and disadvantages? - How do you set it up? And what does a normal workflow look like?
- What are the alternatives?
Why git-secret
?
Git-secret
has a few key advantages that made our team use it:
- It lets you encrypt any kind of file, not just plain-text files!
- It lets you add multiple users to the keyring so that they can simultaneously encrypt/decrypt it. This is very valuable when you have a team of developers who all need access to the secret file.
- It works well on both Linux and Mac, and integrates seamlessly with git.
- The setup is relatively simple and a lot of recurring tasks can be automated with simple scripts.
That said, there are a few disadvantages that we experienced:
- Since it encrypts the whole file, it often leads to conflicts that cannot be auto-merged because there is no specific part of the file that changed.
- For every new key added, the file has to be decrypted and re-encrypted. While there is no way around that in any solution, this may pollute the commit history.
- It does not have good Windows support and therefore must be used on Windows Subsystem for Linux.
How to git-secret
?
Installation
If you are on Mac OS X, this tutorial assumes that you have homebrew installed. It may be necessary to install some of the dependencies below.
If you are using Windows, you will have to use the Windows Subsystem for Linux to follow along. Some of the dependencies below do not have good support for Windows.
The first step is to make sure you have git
installed and working, obviously. Most developers should have it installed already but you can run git --version
just to make sure. If you are on a mac, run brew install git
. If you are on a debian machine, run sudo apt-get install git
. Similar installation commands would exist for other linux distributions. Visit this site to figure it out.
Next up, you will need gnupg
. Again, most linux machines come with this pre-installed so you should be able to run gpg --version
to verify this. Otherwise, install it with the following command: sudo apt-get install gnupg
. On osx, you can install it with: brew install gnupg
. Nothing fancy so far.
Finally, you will have to install git-secret
itself. Detailed instructions can be found here. On a mac, you can just run brew install git-secret
. On debian, you can run the following:
echo "deb https://dl.bintray.com/sobolevn/deb git-secret main" | sudo tee -a /etc/apt/sources.list
wget -qO - https://api.bintray.com/users/sobolevn/keys/gpg/public.key | sudo apt-key add -
sudo apt-get update && sudo apt-get install git-secret
Key Setup
The first thing you want to do is to generate a new GPG key that you will be using with git-secret. I used RSA & RSA with 4096-bit keys.
gpg --gen-key
Then, you need to import everyone else's keys. I set up a folder on our repo called public_keys
and then added a shell script to automatically import/export all keys as following (fill $EMAIL
with your local email used with your key, via a shell argument perhaps):
gpg --import public_keys/*
gpg --batch --yes -a -o public_keys/`echo $USER`.gpg --export $EMAIL
echo "Finished importing and exporting keys"
That's it! This syncs your local keyring with the keys of everyone on your team.
Normal workflow
The steps to use the tool are simple from here on forward.
Step 0: Add the secret file to .gitignore
. Suppose you want to encrypt config/.env
, then you want to add it to .gitignore
so that you don't accidentally push it to source control. Also, git-secret
will not let you add a file to the vault unless it is in your .gitignore
.
Step 1: Add a file to git-secret.
git secret add config/.env
Step 2: Give people access to the file.
git secret tell <EMAIL>
Since we only used GPG for this repo, I could employ an automatic command to give access to everyone on my team. In general, this may not be a safe operation.
for i in `gpg -k | grep -Eo "[^<]+@\S+\.[^>]+"`; do
git secret tell $i
done
Step 3: Encrypt!
git secret hide
Step 4: Decrypt as you wish:
git secret reveal
Note that every time you grant access to new people, you should reveal
and then hide
so that the file is encrypted using new keys.
And that's pretty much it! You can find more detailed docs here.
Deploying
When deploying to production servers or CI, I inject a secret environment variable (e.g. through GitHub Secrets) that uses a base64 encoded string and the python gnupg
package alongside dotenv
to load the configuration file.
What else, if not git-secret
?
There are several other tools like ejson
, blackbox
, and git-crypt
. Most of these tools either have a lot of installation steps, or use a very similar GPG based encryption system, or don't have all of the advantages listed in the first section above.
That said, there is a class of tools that use cloud-based keys like sops
which might be more appropriate for larger teams. While it has a lot more boilerplate and setup involved, it may be a cleaner solution when the number of keys explode to a lot more than a handful, and the drawbacks of git-secret
mentioned above can be addressed through this.
Top comments (3)
Very good and very useful article, this is what I was looking for while searching for git-secret
I'm struggling to see the difference between git-secret and git-crypt.
Are they not both doing the same thing? Encrypting and decrypting files with GPG?
I haven't used git-crypt myself but it looks like it is pretty similar to git-secret :)