Setting up an encrypted git-repository

Solution 1:

A free and partially open-source tool is Keybase :

Git supports remote helpers. And we've made an open source one.

Keybase's remote helper performs all the crypto while letting git do its thing. This might sound impressive, but Keybase has not reimplemented git from scratch. We provide a remote helper, powered by the excellent go-git project, which we've begun contributing to.

We bring to the table: (1) crypto, (2) team + multi-device key management, (3) a safer concept of identity.

It is end-to-end encrypted. It's hosted, like, say, GitHub, but only you (and teammates) can decrypt any of it. To Keybase, all is but a garbled mess. To you, it's a regular checkout with no extra steps.

Even your repository names and branch names are encrypted, and thus unreadable by Keybase staff or infiltrators.

Teamwork is supported via Keybase Teams :

A Keybase team is a named group of people, with flexible membership. Let's say you work on a project called Treehouse. You could register treehouse on Keybase. This team name is universal; there can be only one Keybase team with a given name.

Teams get chats and channels. The chat looks a bit like Slack or Discord:

But Keybase teamwork is end-to-end encrypted, which means you don't have to worry about server hacks.

Keybase

Solution 2:

Step by step instructions, using git-remote-gcrypt and Bitbucket:

Prerequisites

  • GnuPG (brew install gpg on macOS)
  • git-remote-gcrypt (brew install git-remote-gcrypt on macOS)

Overview

This guide will walk you through the process of creating and using a git repo called “gcrypt-sample” with Bitbucket, taking advantage of git-remote-crypt with a dedicated PGP keypair to provide end-to-end encryption.

Every push will be a force push!

Steps

Setting Up

  1. Set up your local and remote repositories:
    • Set up local repository with git init gcrypt-sample
    • On bitbucket.org, create a repository gcrpyt-sample
  2. Set up your ssh key if you haven’t already: ssh-keygen
  3. Add a gcrypt remote: git remote add cryptremote gcrypt::[email protected]:user/gcrypt-sample.git
  4. Generate your GPG keypair. Recommend this guide; for this sample, simply running gpg --gen-key will work.
  5. Configure gcrypt to accept the gpg key you just created:
    1. git config remote.cryptremote.gcrypt-participants <GPG key fingerprint>
    2. git config remote.cryptremote.gcrypt-signingkey <GPG key fingerprint>
  6. Edit your git repo:
    1. echo 'Hello, world!' > hello.txt
    2. git add hello.txt
    3. git commit
  7. git push -u cryptremote master
    • If you have multiple PGP keypairs, you’ll have to cycle through until you get the one you want—this is because you pull before pushing, every time; see the note below.

A note about pulling from the repo

Everytime you pull down (including when you push), you will have to cycle through your PGP keys until you get to the correct one. The reason for this is that the default for git-remote-gcrypt is to use a privacy guard which redacts the identity of the signing key. Consequently, when pulling from the repository, you have to check all of your available keys to see which one is the signing key. The signing key used can be published (and therefore anonymity revoked) by setting the remote.cryptremote.gcrypt-publish-participants property (to anything).

If you set an explicit and singular PGP key for the repo, doing that should be fine. However, doing so does have implications for shared repos (different commits can be tied undeniably to different users).

What’s Encrypted?

To my naked eye, pretty much everything.

What IS encrypted

  • Filenames (including paths)
  • File contents
  • Branches (I don’t know if the first branch pushed is logged under master, but all subsequent ones were)
  • Commit history: There is a single commit (“Initial commit”) and a single date (although dates of your pushes may be tracked by your remote separately, of course—BitBucket’s “Last updated” shows the accurate time. Of course, Bitbucket’s probably not paying attention to the commits themselves—it’s probably assuming you’re doing that.)

What is NOT encrypted

  • Repository name (though that’s obvious enough); just use a codename
  • The number or size of files (they are not distributed in any way); not sure what the implications are for different branches