Protect secrets with git-crypt
How can I protect sensitive data of my git projects such as API tokens or credentials to access databases?
Often vaulting tools are used that require a lot of effort to manage and maintenance, which is not justified for smaller contexts or private projects
In this article I will show you how to use git-crypt to securely keep your application secrets in source code repositories.
1. The common problem with secrets 😕
Many applications need keys or credentials to function, such as access keys to use an S3 bucket.
To deploy these applications on private or public kubernetes infrastructure many organizations adopt the gitops strategy using ArgoCD. This requires that all the manifests required for an application be available in a git repository, including secrets that may contain sensitive information.
Using a private repository is seem like a good solution, but it is also risky. It is easy to forget in a private repository secrets and then later decide to make this repository public, accidentally revealing your secrets, or forget to clean the git history.
Using a vault or a secret manager is often the recommended solution, but for small projects it is onerous and they are not easy tools to implement. Some of these often work only for x86 architectures.
2. Shepherd’s Solution 🐑
Git-crypt could solve some of these problems, with each push your secrets are encrypted on the git repository and with each pull they are decrypted.
2.1 Install git-crypt
There are instructions for Linux, Mac, and Windows on the git-crypt install page Git-crypt is a client available for Linux, Mac, and Windows. In this article explains how to install and usage it on Ubuntu distro:
$ apt install git-crypt
2.2 Create a new repository
$ mkdir myapp && cd myapp
$ git init
$ echo "Hello World!" > README.md
$ git add .
$ git commit -m "First commit"
$ git remote add origin https://github.com/<username>/myapp.git
$ git push -u origin main
2.3 Setup git-crypt
$ git-crypt init
Generating key...
This command generates a symmetric key for this repository, you can copy this key and use it in other repositories. By default, git-crypt stores the generated key in the file .git/git-crypt/keys/default, this is the key that can decrypt all encrypted files in the repository.
Using the file called .gitattributes, it is possible to add metadata to files and folders to indicate which ones we want to encrypt. Since we are starting from a new repository in this example, we must create an empty .gitattributes file and use this syntax:
# Files to encrypt
filename attr1=value1 attr2=value2
folder/** attr1=value1 attr2=value2
To enable encryption of the desired files you need to specify two attributes filter and diff both configured with value “git-crypt”.
# Files to encrypt
s3-credentials filter=git-crypt diff=git-crypt
secrets/** filter=git-crypt diff=git-crypt
2.4 Test configuration
Add the newly configured .gitattributes file to our git repository and commit it:
$ git add .gitattributes
$ git commit -m "Add .gitattributes"
$ git push
We can now create the file containing the credentials of an S3 bucket in the repository.
Tip
Before using real values, test the configurations using dummy values
$ cat <<EOF>> s3-credentials
[default]
aws_access_key_id = <dummy private key>
aws_secret_access_key = <dummy private access key>
EOF
We can check the status of the file before pushing the s3-credentials file into git.
$ git-crypt status
encrypted: s3-credentials
not encrypted: .gitattributes
This means that the file will be encrypted when placed in the git repository, so we add the file and commit:
$ git add s3-credentials
$ git commit -m "Add s3-credentials"
$ git push
2.5 Check encryption status
The use of git-crypt is transparent, in fact if you check the file with the cat command, you will notice that locally it is still in plain text, whereas if you try to open it from a browser or by cloning the repository again, the file is encrypted.
$ cat s3-credentials
[default]
aws_access_key_id = <dummy private key>
aws_secret_access_key = <dummy private access key>
$ file s3-credentials
s3-credentials: ASCII text
if you want to check locally what your files would look like after the commit you can run the command:
$ git-crypt lock
$ file s3-credentials
s3-credentials: data
$ cat s3-credentials


