Storing secrets in git

So I gave into the temptation to store "secret" data into a git repository. Of course, to keep things safer, I chose to use an encryption tool. So I tested:

git-secret

So, I tested git-secret. It seems to work but was in my opinion cumbersome.

Furthermore, the version I tested, which was the one from the void has a bug whereby adding files for encryption would update the .gitignore file but would forget to put an EOL at the end of the file.

The main issue I have is that you need to explicitly issue the command:

git-secret hide

To hide files. Alternatively you can include this in your pre-commit hook, but that brings its own issues along.

Overall it was not the best experience.

git-crypt

At the end I opted for git-crypt, which is more seamless and requires less user interaction for it to work.

git-crypt mini howto

I installed git-crypt using my distro package installation command.

Initialize an existing git repo and export encryption key:

cd repo
git-crypt init
git-crypt export /path/to/key

The exported key now needs to be shared between all the repo users. For example can be saved into a secret variable in the CI/CD pipeline system.

Select the files that need to be protected by creating a .gitattributes file:

secretfile filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt
secretdir/** filter=git-crypt diff=git-crypt

Like a .gitignore file, it can match wildcards and should be checked into the repository. Make sure you don't accidentally encrypt the .gitattributes file itself (or other git files like .gitignore or .gitmodules).

NOTE Make sure your .gitattributes rules are in place before you add sensitive files, or those files won't be encrypted!

After cloning a repository with encrypted files, unlock with the secret key:

git-crypt unlock /path/to/key

That's all you need to do - after git-crypt is set up (either with git-crypt init or git-crypt unlock), you can use git normally - encryption and decryption happen transparently.

Verifying that git-crypt is working

  • The simplest way:
    • git crypt status
  • The native way:
    • git check-attr -a -- <path>
  • Checking object hashes (these shouldn't match):
    • git hash-object <path>
    • cat <path> | git hash-object --stdin