Last Updated: September 09, 2019
·
23.44K
· mavimo

Protect secret data in git repo

We use Ansible to manage our infrastructure, so a lot of configurations are stored in a git repository. Some of this configuration are potential dangerous if made public (like SSL certificate, GPG keys, ...) therefore we prefer to encrypt this data in the git repository.

To encode this data we use git-crypt.

Install git-crypt

Depending on your OS you need to install git-crypt, with homebrew is really simple:

brew install git-crypt

and after completing download you can run it:

$ git-crypt --help

And you can read:

Usage: git-crypt COMMAND [ARGS ...]

Valid commands:
 init KEYFILE   - prepare the current git repo to use git-crypt with this key
 keygen KEYFILE - generate a git-crypt key in the given file

Plumbing commands (not to be used directly):
 clean KEYFILE
 smudge KEYFILE
 diff KEYFILE FILE

Init a new repo

You need a git repo to start, let's create one and initialize it:

mkdir -p ~/ansible/test_crypt
cd ~/ansible/test_crypt
git init .

now we need to inizialize git-crypt in repo, before this we need to create a encrypt key (if you already have a key from other source, like someother that send you file skyp this step):

git-crypt keygen ~/ansible/crypt-key

this key need to be out of repo (otherwise if a use can clone repo can also decode your file).

Now we enable git-crypt on our repo:

cd ~/ansible/test_crypt
git-crypt init ~/ansible/crypt-key

Crypt files

We are ready to insert some file and crypt they in our repo. This operation is really easy, we just edit .gitattributes file:

vi  ~/ansible/test_crypt/.gitattributes

and specify what files need to be encoded, eg:

*.cert filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt
*.crt filter=git-crypt diff=git-crypt
*.gpg filter=git-crypt diff=git-crypt

but we can also encode specific files (eg files with passwords):

vars/agavee.com/passwords.yml filter=git-crypt diff=git-crypt

Start test

Create a simple file in repo and commit it:

echo "This is a public file" > README.md
echo "my_key" > secret.key
git add README.md
git add secret.key
git add .gitattributes
git commit -m "Init repo"
# we can also add remote and push on remote

We can read content of files:

cat README.md
cat secret.key

but if someone clone our repo?

git clone ~/ansible/test_crypt ~/ansible/thief
cat ~/ansible/thief/README.md
cat ~/ansible/thief/secret.key

as you can see user that clone our repo can't read content of secret file, if we supply the key to our firend it can add the key to repo and file content wll be visible:

git clone ~/ansible/test_crypt ~/ansible/friend
cd  ~/ansible/friend
git-crypt init  ~/ansible/crypt-key
cat ~/ansible/friend/README.md
cat ~/ansible/friend/secret.key

NB: never store crypt key in the same server of you repo!

Note

git-crypt actually is at version 0.3, there may be backwards-incompatible changes introduced before version 1.0.

git-crypt encrypts files using AES-256 in CTR mode with a synthetic IV
derived from the SHA-1 HMAC of the file.

The AES key is stored unencrypted on disk. The user is responsible for
protecting it and ensuring it's safely distributed only to authorized
people.

There are also plans to add additional key management schemes, such as passphrase-derived
keys and keys encrypted with PGP.

git-crypt is NOT NOT NOT NOT NOT designed to encrypt an entire repository.

Authored by Marco Vito Moscaritolo

3 Responses
Add your response

I would add the crypt-key to .gitignore to make sure it is never added :)

over 1 year ago ·

You're right, but will be better have key outside of repo ;)

over 1 year ago ·

Hi! Thanks for this share!
Please, may I ask you, how do you encrypt files which have already been committed before implementing git-crypt?

over 1 year ago ·