44

Is it possible to automatically encrypt files via 'git push' before transferring to a remote repository? And automatically decode them while 'git pull'.

I.e, if I have some remote server with shared access with git repository there, and I don't want our project to be stolen without a permission... Maybe there is some special git-hooks before push and after pull?

hoijui
  • 3,615
  • 2
  • 33
  • 41
UncleMiF
  • 1,051
  • 2
  • 11
  • 20
  • 2
    A similar question was asked on the Git mailing list in July 2009: http://thread.gmane.org/gmane.comp.version-control.git/123466/focus=123485 – Tim Henigan Mar 16 '10 at 18:24
  • 1
    I alose found a discussion here: https://kerneltrap.org/mailarchive/git/2008/3/13/1153274/thread – UncleMiF Mar 16 '10 at 20:17
  • kerneltrap link's dead – Daniel May 02 '15 at 15:34
  • Thanks to the [archive](https://archive.org), the content survives: [kerneltrap.org/mailarchive/git/2008/3/13/1153274/thread](https://web.archive.org/web/20090131024526/https://kerneltrap.org/mailarchive/git/2008/3/13/1153274/thread) – ominug Jul 17 '17 at 16:41

5 Answers5

24

Yes and no.

You could try to depend on hook but that supposes they are installed at the remote locations, and that is not always reliable.

Another way to achieve almost the same effect would be by using a smudge/clean attribute filter driver, but not for a full repo.

smudge/clean

(Source: Pro Git book: Customizing Git - Git Attributes)

That way the smudge script is able decode the files, while the clean script would encode them.
Again, that could work for a few sensitive files, not for a full repo.

Off course, those scripts would not be in the repository itself, and would be managed/communicated by another way.

As Alkaline points out in the comments, that idea does not scale for a repo, as the main git maintainer Junio C. Hamano comments back in 2009:

As the sole raison d'etre of diff.textconv is to allow potentially lossy conversion (e.g. msword-to-text) applied to the preimage and postimage pair of contents (that are supposed to be "clean") before giving a textual diff to human consumption.

The above config may appear to work, but if you really want an encrypted repository, you should be using an encrypting filesystem.
That would give an added benefit that the work tree associated with your repository would also be encrypted
.


Even though it does not scale to a full repo, the idea was implemented (3 years later in 2013) with git-crypt, as detailed in Dominic Cerisano's answer.
git-crypt uses a content filter driver (implemented in cpp, with commands.cpp setting up your .gitattributes with the relevant smudge and clean filter commands).
As any content filter driver, you can then limit the application of git-crypt to the set of files you want, in the same .gitattributes file:

secretfile filter=git-crypt diff=git-crypt
*.key filter=git-crypt diff=git-crypt

As mentioned in the README:

git-crypt relies on git filters, which were not designed with encryption in mind.

As such, git-crypt is not the best tool for encrypting most or all of the files in a repository.
Where git-crypt really shines is where most of your repository is public, but you have a few files (perhaps private keys named *.key, or a file with API credentials) which you need to encrypt.

For encrypting an entire repository, consider using a system like git-remote-gcrypt instead.

(see more at spwhitton/ tech/ code/ git-remote-gcrypt, from Sean Whitton)

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Very good advice! Thanks. I think this method is very useful with custom .gitattributes rules! – UncleMiF Mar 16 '10 at 19:30
  • See also http://stackoverflow.com/questions/1557183/is-it-possible-to-include-a-file-in-your-gitconfig – VonC Apr 23 '10 at 05:58
  • @Daniel it works with any local repo: the clean script restore the encrypted version on commit. What is pushed (to, for instance, GitHub) is therefore encrypted. – VonC May 02 '15 at 15:31
  • Thanks. It looks like there's an image missing from the answer. My browser displays "alt text" after "smudge/clean attribute filter driver" above. – Daniel May 02 '15 at 20:10
  • @Daniel I have restored the picture – VonC May 02 '15 at 20:23
  • Thanks again. Is there any way you could provide code for this method? – Daniel May 04 '15 at 13:41
  • Junio C Amano (the maintainer of the git codebase) has warned against using smudge this way. http://article.gmane.org/gmane.comp.version-control.git/113221 – Bernard Nov 01 '15 at 07:41
  • 1
    @Alkaline Good point. I have made that warning explicit in the answer. – VonC Nov 01 '15 at 08:53
  • Note that git-crypt is for selectively encrypting remote assets, not entire repositories. Also note most git service providers (eg. GitHub, BitBucket) do not provide encrypted storage, even on [their](https://www.youtube.com/watch?v=R4FwJdBb6_M&t=3m31s) 'private' repositories. Git-crypt is actual encrypted storage, independent of git service providers. – Dominic Cerisano Jul 16 '17 at 20:49
  • Link for `git-remote-gcrypt` has left the house. – ipatch Jul 02 '18 at 16:22
  • @Chris For an 8-years old answer, I am not surprised. I have updated and documented the link to the new `git-remote-gcrypt`. – VonC Jul 02 '18 at 16:30
12

You can take a look at this project: https://github.com/shadowhand/git-encrypt

UPDATE: This above project is deprecated and recommends using https://github.com/AGWA/git-crypt

Tzach Zohar
  • 37,442
  • 3
  • 79
  • 85
Lluís
  • 1,267
  • 1
  • 14
  • 36
  • Guessing it's because the project says there's some controversy and points to article.gmane.org/gmane.comp.version-control.git/113221 – Daniel May 02 '15 at 15:42
  • Limitations: git-crypt does not work reliably with some third-party git GUIs, such as Atlassian SourceTree and GitHub for Mac. Files might be left in an unencrypted state. – huang Jan 09 '22 at 05:57
8

How to secure public and private remote assets using git-crypt.

  • Transparent to all git clients and services (eg. GitHub, BitBucket, etc).
  • Linux, OSX and Windows support.
  • Asset level encryption (see VonC's answer).
  • AES-256 cipher.

Create your 256 bit private key (RETAIN AND PROTECT THIS KEY)

sudo apt install git-crypt 
mkdir key; cd key;
git init; git-crypt init
git-crypt export-key ~/crypt.key


Push a file called .gitattributes to each repo's root directory.
It should contain one asset pattern per file, directory or type you wish to encrypt:

docs/doc.txt  filter=git-crypt diff=git-crypt
js/**         filter=git-crypt diff=git-crypt
*.java        filter=git-crypt diff=git-crypt
src/cpp/*.h   filter=git-crypt diff=git-crypt


Encrypt assets in each repo:

cd repo-root-directory
git-crypt unlock ~/crypt.key
git-crypt status -f
Push (from command line or git client)


Continue your git workflow as usual.

  • Run git-crypt unlock ~/crypt.key once on any new clones of these secured repos.
  • You may wish to purge old unencrypted commit histories on all branches and tags.
  • If you use a git client, it must fully support git filters and diffs.



Dominic Cerisano
  • 3,522
  • 1
  • 31
  • 44
6

There are two ways to do this.

One is to use a project like git-crypt, http://www.agwa.name/projects/git-crypt/ which adds in fiters to pull and push process, or set up the filters manually as described here https://gist.github.com/shadowhand/873637

Another way if you are working in a linux environment, is to use ecryptfs. For this scenario, in base of your project directory you could, for example, create two directories

project/encrypted_src

project/src

Then from the root of the project directory you would mount using the command

sudo mount -t ecryptfs encrypted_src src

entering a pass-phrase and accepting the defaults when prompted. At this point, files placed in src/ will be encrypted into encrypted_src/ on the fly. When you are finished just

sudo umount src

and only the encrypted files remain. Essentially files are committed and pushed from encrypted_src/ and edited in src. As long as everyone uses the same pass-phrase (or mounts with the same key) the repo can be shared among developers. Also you can get fancier. You can encrypt file names as well as just file contents, or encrypt different folders in a repo with different pass-phrases or keys. The last feature is nice if you have configuration files with sensitive access information that individual groups (dev, test, production) will want to maintain privately.

That said, though, be aware that once you start encrypting stuff. You loose a lot of the advantages of source control like being able to see diffs between various commits. If you have a project of any size the ability to review commits will be invaluable. If you expect bugs, at some point or another, the ability to analyse and find their point of introduction by back tracking through commit history will also be invaluable. So secure your server first and then use encryption only where in makes sense to protect sensitive info in source control. Just my 2 cents.

oz123
  • 27,559
  • 27
  • 125
  • 187
user2851586
  • 61
  • 1
  • 2
1

There are Tahoe-LAFS hooks provided by git-annex, which admittedly might be more complicated than you need.

Jeff Burdges
  • 4,204
  • 23
  • 46