Skip to content

Let’s keep this our secret – Transparent Git encryption using git-crypt

Storing sensitive or secret information within a Git repository is never a good idea, at least as long as you do it unencrypted. Whoever has access to the Git repository, can view and change this sensitive data. Storing encrypted data within a Git repo has also the downside, that you need to decrypt it while you want to work with the data and you have to remember to reencrypt it, before pushing it back again. Here comes git-crypt into play. Git-crypt gives you a transparent method to de- and encrypt data during pulling and pushing from or to your Git repository.

Git-crypt is a save and easy way to handle your sensitive data and push it to whatever Git repository you like. It’s not important if this is Github, Gitlab or some self-hosted solution. It’s just Git right? The charming idea behind it is, that you can share secret information in a public repository. It’s also a good idea to encrypt this data within a private repository. Whatever baddy get’s access to it, will still only find encrypted data and without the valid git-crypt or GPG key, he will not be able to decrypt it.

As always, you can find more information about git-crypt in the official Github repository here.

To get things started, you need obviously have installed git on your client. In addition, you have to install git-crypt. It’s available in the Ubuntu software repositories. So you can install it by doing the following:

sudo apt install git-crypt

Now head to your local repository location where you have cloned your Git repo to. To get it git-crypt initialized, enter this:

git-crypt init
Generating key...

You have two ways to work with a git-crypt encrypted repository. Either by using the repository git-crypt key which was generated during the git-crypt init command, or by generating your own GPG key and add this key (and all keys of your co-workers) to the repository. Nevertheless, it’s always a good idea to store the repository key in a safe location. You can imagine it as the “master key” to the repo if everything else fails. You may export the repository key like this:

git-crypt export-key /tmp/git-crypt-repo.key

Now let’s generate your own GPG key. You may already have one, then you can reuse it here also. The chances are high, that you may need a GPG key later anyway. You will get asked for a passphrase during the process. Be aware, if you enter a passphrase, you will get asked everytime for it, when working with the secret data. So I leave it blank for this demo. To generate your GPG keypair, do as below:

❯ gpg --generate-key
gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Note: Use "gpg --full-generate-key" for a full featured key generation dialog.

GnuPG needs to construct a user ID to identify your key.

Real name: My real name
Email address: some.email@mymail.com
You selected this USER-ID:
    "My real name <some.email@mymail.com>"

Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 62B21020B1E5D774 marked as ultimately trusted
gpg: directory '/home/username/.gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as '/home/username/.gnupg/openpgp-revocs.d
/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.rev'
public and secret key created and signed.

pub   rsa3072 2022-04-13 [SC] [expires: 2024-04-12]
      /XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
uid                      My real name <some.email@mymail.com>
sub   rsa3072 2022-04-13 [E] [expires: 2024-04-12]

So now, that we have our GPG key, we can import it into the git-crypt repo. Just provide your users email address you statet above:

git-crypt add-gpg-user some.email@mymail.com
[master (root-commit) 5ac3334] Add 1 git-crypt collaborator
 2 files changed, 4 insertions(+)
 create mode 100644 .git-crypt/.gitattributes
 create mode 100644 .git-crypt/keys/default/0/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.gpg

So one last thing is needed before we can commit and push our changes. Our secret data! Add a secret file to your cloned repository, but first, create a file called .gitattributes within your projects root directory. In there, you tell which files, folders or combination of both should be encrypted. In my case, my file secret-file.txt should be encrypted.

secret-file.txt filter=git-crypt diff=git-crypt

It’s a good idea to work with wildcards here. You can find more examples in the official Github repository.

So, add all the files we’ve created and commit your changes, then push it to the remote repo and let’s see, what the WebUI of Github says us when trying to view the encrypted file.

git add secret-file.txt
git add .gitattributes
git commit -m "Added secret information"
git push
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 12 threads
Compressing objects: 100% (8/8), done.
Writing objects: 100% (11/11), 1.57 KiB | 1.57 MiB/s, done.
Total 11 (delta 0), reused 0 (delta 0)
Trying to view the encrypted file on Github

As you can see, you can’t see! The file is encrypted and Github does not know what to do with it. You can try to download the file, you will only see rubish in it.

So success right? Kind of, one last thing I want to mention. If you change your client or a co-worker of you starts to work on the repository, you have to unlock the repository after initially cloning it. This is a one-time action and will only work, if you provide the respository key, or your GPG keyring has the GPG key in it, you’ve added to the repo earlier.

To unlock the repository, just enter the following:

git-crypt unlock
# or to use the repository key to unlock it
git-crypt unlock /tmp/git-crypt-repo.key

Now you’re able to view and work with your secret-file.txt again.

cat secret-file.txt
This is a super secret file, noone else should be able to see it!

Philip

2 thoughts on “Let’s keep this our secret – Transparent Git encryption using git-crypt”

  1. You should talk about the assumptions of git-crypt:
    1. Only works on Linux systems (AFAIK).
    2. You are (not?) recommending it for encrypting *ALL* files in your git repo.
    3. Therefore, is not the same as “encrypted git” (web search for “Keybase”).

    1. Avatar photo

      Hello,

      regarding 1. There is Windows experimental support. You can also use it under Windows using WSL. Also it’s supported on Mac.
      regarding 2. No, I don’t recommend to encrypt all files in a repo blindly, you can do so for sure. So, up to you.
      regarding 3. I don’t get your point.

      Philip

Leave a Reply

Your email address will not be published. Required fields are marked *