Skip to content

Instantly share code, notes, and snippets.

@gatoniel
Last active August 14, 2023 17:43
Show Gist options
  • Save gatoniel/151ddb6dda053339630d901312a38df3 to your computer and use it in GitHub Desktop.
Save gatoniel/151ddb6dda053339630d901312a38df3 to your computer and use it in GitHub Desktop.

Syncing between encrypted Git Repositories

Sometimes you want to keep folders in sync across different computers with some kind of file versioning, maybe you also want some kind of backup. You could use a private repository on GitHub, Bitbucket or Gitlab for that. However, when that data is particularly private, you might want to encrypt your data. git-remote-gcrypt can do that for you. As other guides on that topic were not very specific about syncing between two different computers, this guide focuses on that.

Other Sources

These are the sources I used:

Prerequisities

I assume that you have setup separate gpg keys on your two computers (key1 on machine 1, key2 on machine 2). Additionally you should create a preferabily private repository on Bitbucket, GitLab or GitHub. Here, I assume a GitHub repository that I connect to via ssh.

Installation

You should be able to install git-remote-gcrypt easily via

sudo apt install git-remote-gcrypt

or the equivalent statement in your distro. Otherwise the above sources have more information on the installation.

Global configs on both machines

Compatibility with gpg-agent

In order to use the gpg-agent to sign and decrypt the repository run the following command on both machines

git config --global --add gcrypt.gpg-args "--use-agent"

Optional: publish participants

see this note: https://manpages.debian.org/testing/git-remote-gcrypt/git-remote-gcrypt.1.en.html#gcrypt.publish To use the option run on both machines

git config --global --add gcrypt.publish-participants true

Exchange gpg keys

see also here: https://www.gnupg.org/gph/en/manual/x56.html

  1. On machine 1 run: gpg --output key1.pgp --armor --export key1
  2. and on machine 2: gpg --output key2.pgp --armor --export key2
  3. Copy the file key1.gpg to machine 2 and vice versa with key2.gpg.
  4. Then run on machine 1: gpg --import key2.gpg
  5. and on machine 2: gpg --import key1.gpg
  6. After importing the keys you have to validate them as explained in the link above.

Of course you could also use only one key. Then you need to copy the secret key from one machine to the other.

Setup

Initial push on machine 1

  1. cd into the folder that you want to sync or backup
  2. git init
  3. Run git remote add origin gcrypt::git@github.com:<USER>/<MY_REPO>.git
  4. Add the keys that are used to encrypt the repository: git config remote.origin.gcrypt-participants "key1 key2"
  5. In case that key1 is not your default signing key on machine 1, add it as signing key for this repository with git config remote.origin.gcrypt-signingkey "key1".
  6. Add erverything git add .
  7. And commit: git commit -m "Initial commit"
  8. Optional: git branch -M main
  9. And push the repository: git push -u origin main

Clone on machine 2

  1. git clone gcrypt::git@github.com:<USER>/<MY_REPO>.git
    1. In case you get prompted to type in the password for your gpg key, cancel until you see that you`re typing the password for the correct key.
    2. Ignore the warning: You appear to have cloned an empty repository.
  2. Then cd into the newly created folder.
  3. git pull origin main
  4. And switch to correct branch: git checkout main
  5. Add the participants list on this machine: git config remote.origin.gcrypt-participants "key1 key2".
  6. In case that key2 is not your default signing key on machine 2, add it as signing key for the repository on machine 2 with git config remote.origin.gcrypt-signingkey "key2".

Test syncing between both machines

  1. Add and commit a change on machine 2.
  2. git push
  3. Run git pull on the first machine. See the newly added content.
  4. Do the same three steps on machine 1 and pull on machine 2.

Troubleshooting

gcrypt: Failed to decrypt manifest!

Make sure that the key that is used to sign the manifest file is in the keys listed in remote.origin.gcrypt-participants. Use the config variables user.signingkey or remote.origin.gcrypt-signingkey to specify the key that is used for signing.

If you want to use a separate key (key3) to sign your git commits from the keys in the remote.origin.gcrypt-participants list (key1 and key2) you need to use the following config:

git config user.signingkey "key3"
git config remote.origin.gcrypt-participants "key1 key2"
git config remote.origin.gcrypt-signingkey "key*"  # Use the correct key depending on your machine!

Therefore the git config variables have the following functions in connection with git and gcrypt

  • To sign your commits, git uses user.signkey
  • To sign the manifest file, gcrypt uses remote.origin.gcrypt-signingkey. If that is not set, gcrypt bounces back to user.signingkey. Whichever key is used to sign the manifest, this key needs to be part of the remote.origin.gcrypt-participants list.
  • gcrypt encrypts your repository, so that it can be decrypted with the keys listed in remote.origin.gcrypt-participants.

restart gpg-agent

In many cases it does make sense to restart gpg-agent with gpgconf --kill gpg-agent or restart your terminal. This will solve the not found issues as mentioned here: https://manpages.debian.org/testing/git-remote-gcrypt/git-remote-gcrypt.1.en.html#KNOWN_ISSUES

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment