How to Use Git-crypt to Encrypt Sensitive Files in Git
CI/CD and process automation require working with sensitive data such as server credentials, keys to the API's of external providers, or keystore files used to sign mobile apps before uploading them to the online store. Usually, such data is stored within environment variables defined in the CI/CD tool. In some cases, though, it may be more convenient to store it in the Git repository – managing changes is easier, as well as sharing and browsing history.
However, once you decide to keep the data in the Git repository, it is strongly recommended to protect it with some form of secure encryption, Buddy app being fully equipped with correct tools for the job.
In this guide, we will describe how to do it with git-crypt and how to configure a pipeline that will automatically encrypt and decrypt files upon every push. This guide doubles as a practical git-crypt documentation for setup and CI/CD.
git-crypt on GitHub: Official Repo and Documentation
git-crypt is developed on GitHub. For the official source code and full documentation, see the git-crypt repository. Below we show how to install, configure, and use it with Buddy pipelines.
What is git-crypt? Encrypt files in Git
If you need to encrypt files in Git (secrets, keys, configs), git-crypt is a standard solution. In short, it lets you encrypt and decrypt files with GPG (GNU Privacy Guard) keys in the background of Git commands. Once the tool is properly configured, the files are encrypted on push to and decrypted when fetched from the remote server.
The tool encrypts files on a per-file basis, meaning you can choose which files to encrypt and which to keep unencrypted. This allows you to protect sensitive data, such as passwords or private keys, while still collaborating with others on the non-sensitive parts of the Git repository.
git-crypt Documentation and Installation
Install git-crypt and GPG
To install git-crypt on MacOS, run
bashbrew install git-crypt brew install gpg$$
To install git-crypt on Linux, run
bashapt-get install -y git-crypt sudo apt-get install gnupg$$
Repository and git-crypt initialization
First, create a new directory and add two files:
bashmkdir myrepo cd myrepo echo “everybody can read it” > README.md echo “this file has sensitive data” > secrets.txt$$$$
After that, initialize Git and git-crypt with the git-crypt init command:
bashgit init git-crypt init$$
Defining files to encrypt
In the directory with the sensitive data, add a .gitattributes file and define which files should be encrypted. You can add files any file extension (e.g. *.pdf for just PDF files). In our case, this will be a single file secrets.txt:
secrets.txt filter=git-crypt diff=git-crypt
Create new definitions for each file. You can also add patterns in the following way:
*.key filter=git-crypt diff=git-crypt
secretdir/** filter=git-crypt diff=git-crypt
A good practice is to add a line to prevent encrypting the .gitattributes file itself:
.gitattributes !filter !diff
Testing encryption
To check if the defined conditions work, run the following:
bashgit-crypt status -e$
Commits, pushes & encryption
From now on the files will be automatically encrypted on every push, i.e. you will be able to read and edit them in your local working copy, but on the remote and in other working copies the files will be encrypted.
Create a new Git repository with your provider and push it to the remote:
bashgit add . git commit -m ‘init commit’ git remote add origin REMOTE_URL git push master$$$$
Once you open secrets.txt on the remote, you will see that it’s an encrypted binary file:
Image loading...
Working in team with git-crypt
If an unauthorized person (i.e. without a proper GPG key) clones the repository, the files in their working copy will also be encrypted files. If you want your teammates to view and edit those encryped files, you can do one of two things:
- Share the encryption key with them (symmetric key).
- Add their GPG key to authorized keys.
git-crypt unlock with symmetric key
Teammates can decrypt the repository with git-crypt unlock using a shared key. Begin with exporting the key that you used for encryption using the git-crypt export-key command:
bashgit-crypt export-key path/where/key/should/be/saved$
The exported key should be passed to your team members in a secure way. They can now decrypt the repository by running:
bashgit-crypt unlock path/to/key$
git-crypt lock. All newly fetched changes will also be decrypted automatically.
GPG key
First, the person we want to authorize needs to create their own GPG key. While creating it, they will be asked to enter an e-mail address:
bashgpg --gen-key$
After that, they need to list the keys and copy the key ID:
bashgpg --list-keys$
The last step is printing the key and passing it to the admin that will be granting the permissions to git-crypt:
bashgpg --export --armor $KEY_ID$
Now, the admin that grants the git-crypt rights has to save the GPG key on their disk and import it with the following command:
bashgpg --import /path/to/file$
After importing it, they need to add the key as trusted to git-crypt in the repository:
bashgit-crypt add-gpg-user --trusted $EMAIL$
After committing changes to the repository, the new user is now able to decrypt all the encrypted files in their working copy by running:
bashgit-crypt unlock$
How to use git-crypt in CI/CD process
Secret data, such as config files, API keys, or certificates, needs to be decrypted during the application deployment. Usually, this is done using the symmetric key, the process looking exactly as we described it in the Symmetric key paragraph.
git-crypt unlock and lock in the pipeline
All of the above can be automated with a properly configured delivery pipeline: run git-crypt unlock to decipher the files, build and deploy the application, then git-crypt lock to secure them again.
Image loading...
The decryption is performed with git-crypt unlock: the symmetric key is uploaded to the Unlock action, which uses it to decipher the files in the pipeline filesystem.
Image loading...
Once all tasks are performed, you can secure the files once again with Git-crypt lock.
Image loading...
Additional resources
Official git-crypt documentation (GitHub)
- git-crypt repository — source code and full documentation
API documentation
Actions used in this guide
Jarek Dylewski
Customer Support
A journalist and an SEO specialist trying to find himself in the unforgiving world of coders. Gamer, a non-fiction literature fan and obsessive carnivore. Jarek uses his talents to convert the programming lingo into a cohesive and approachable narration.