

Storing sensitive data in a git repository using git-crypt - paolomainardi
http://www.twinbit.it/en/blog/storing-sensitive-data-git-repository-using-git-crypt

======
zimbatm
After 4 months of usage, I don't recommend using git-crypt.

The main issue is that because transforms between the encrypted and decrypted
state are transparent, it's very easy to commit files in clear that should
have been encrypted. The .gitattributes patterns are not always obvious. Also
.gitattibutes doesn't support encrypting the whole repo because it's lacking
the negating parameter that allow you to encrypt everything except the
.gitattribute file.

The second issue is that a lot of times I ended up having my repo in an
inconsistent state. Some times, especially during rebases, something would go
wrong and encrypted files would get marked as dirty even if they haven't
changed. Running `git checkout` on these files would not work to put them back
in a consistent state. I would have to remove the git-crypt config in
.git/config and reset the repo to fix the issue. Some times the file didn't
decrypt properly, although thing might have been an issue between the
combination of git and git-crypt versions.

So in short, git-crypt is an awesome idea but I think is at the wrong level of
abstraction. It relies on feature that haven't really been designed for
security.

EDIT: To be a bit more constructive: the first issue could be mitigated by
adding a `git-crypt check <path>` that tells you if a file is encrypted or not
behind the scene.

~~~
agwa
Thanks for your feedback. It's true that there are still edge cases where the
repo can get in an inconsistent state. This is the biggest issue I need to
address before the 1.0 release. I should be able to provide commands that will
fix up the repo if this happens. And thanks for pointing me in the direction
of rebases - I clearly haven't done enough testing with them.

As for security, .gitattributes actually does have negation capability (see
the article for an example) so you can encrypt the whole repo by default and
explicitly whitelist files to not be encrypted. But I must emphasize that if
you are encrypting most or all of the files in your repo, git-crypt is not the
best tool because as you point out, git filters haven't really been designed
for this. Where git-crypt really shines is where most of your repo is public,
but you have a few files (perhaps private keys named *.key, or a file with API
credentials) which you need to encrypt. I do like your suggestion of a command
to check if a file is being encrypted, and plan to implement that.

~~~
zimbatm
I had to go back to the man pages. I think I got stuck at the "Unlike
.gitignore, negative patterns are forbidden." and missed that you could unset
attributes instead :)

In the process I also found `git check-attr` that goes 90% of the way of the
`git crypt check` idea. Eg: `git check-attr -a -- path/to/file` will output
git-crypt if the file is encrypted. A `git crypt ls` that lists all the
encrypted files could be useful too to give more visibility.

~~~
agwa
> In the process I also found `git check-attr` that goes 90% of the way of the
> `git crypt check` idea. Eg: `git check-attr -a -- path/to/file` will output
> git-crypt if the file is encrypted. A `git crypt ls` that lists all the
> encrypted files could be useful too to give more visibility.

That's extremely useful - thanks for passing on that info!

------
agwa
git-crypt author here. This is a nice article on git-crypt.

There's a major new feature in the pipeline for git-crypt: GPG support. You'll
be able to easily grant access to collaborators (or to yourself, on a
different device) by running `git-crypt add-collab _GPGKEYID_ `. There will no
longer be a need to schlep a symmetric key file around.

GPG support is currently on a feature branch and undergoing testing. See
[https://github.com/AGWA/git-crypt/issues/3](https://github.com/AGWA/git-
crypt/issues/3) if you're interested.

~~~
grota1981
author here, thanks for the project, for the gpg based feature branch and for
liking the article!

------
roller
Another similar project that aims to do the same thing:
[https://github.com/elasticdog/transcrypt](https://github.com/elasticdog/transcrypt)

The readme contains an itemized comparison, though it sounds some of this
actual comparison may be out of date or more specific to git-encrypt (yet
another project) git-crypt does appear to use openssl libraries for example.

transcrypt is just a Bash script and does not require compilation

transcrypt uses OpenSSL's symmetric cipher routines rather then implementing
its own crypto

transcrypt does not have to remain installed after the initial repository
configuration

transcrypt generates a unique salt for each encrypted file

transcrypt uses safety checks to avoid clobbering or duplicating configuration
data

transcrypt facilitates setting up additional clones as well as rekeying

transcrypt adds an alias git ls-crypt to list all encrypted files

~~~
agwa
Cool, thanks for pointing me towards transcrypt - I hadn't heard of it until
now. You are correct: git-crypt does use the OpenSSL libraries; we do not roll
our own crypto.

I'm happy to see transcrypt didn't make the most common crypto mistake that
Git crypto projects made, which is to use a block cipher in ECB mode or CBC
mode with a fixed IV. That said, I don't think it's a good idea to implement
this with shell scripts. While shell scripts are extremely convenient, it's
very hard to write them securely. For example, in one place transcrypt leaks
your passphrase as an argument to an openssl command, meaning there's an
instant where another user could see it in the output of `ps`.

------
sigil
I use gitcrypt to keep sensitive configuration data out of git history, while
still being able to diff, log, merge etc those files. It works well for that.

Note, gitcrypt uses symmetric encryption and stores the shared key in your
gitconfig. It would be nice to use gpg instead for git's "smudge" and "clean"
filters, but I can't for the life of me get a sane gpg-agent forwarding setup
going, which renders that idea pretty useless.

Anyone have suggestions there?

~~~
agwa
git-crypt author here. GPG support will be the upcoming release (see my other
comment). It's actually not as simple as just putting gpg in the smudge and
clean filters, since gpg's non-deterministic encryption confuses git.

Afraid I can't help with your gpg-agent forwarding. The few times I've needed
to do that I had to proxy the GPG agent connection via socat and through ssh
port forwarding, which is not very sane (but might be improved with a few
well-designed scripts).

~~~
sigil
_GPG support will be the upcoming release (see my other comment)._

Saw that -- awesome. I rolled something similar where gitcrypt.salt and
gitcrypt.pass were stored in a gpg-encrypted file. After cloning, you decrypt
once with gpg, then un-smudge all the encrypted files. No more gpg after that.

How does your solution differ? Is the shared gitcrypt.pass gone entirely? Do I
potentially need access to a gpg keyring every time I checkout, diff, log,
etc?

 _The few times I 've needed to do that I had to proxy the GPG agent
connection via socat and through ssh port forwarding, which is not very sane._

Yeah, it's too messy for me. My question was, if ssh-agent can be forwarded,
why can't gpg-agent be forwarded? Boy was that a rabbit hole.

It seems the ssh-agent forwarding protocol is specific enough that it couldn't
be used for gpg-agent.

Also, while gpg-agent can apparently stand in for ssh-agent when it comes to
ssh keys, ssh-agent can't stand in for gpg-agent with gpg keys.

Furthermore, I got the sense that the gpg folks don't even want gpg-agent
forwarding either -- too insecure for them.

~~~
agwa
> Saw that -- awesome. I rolled something similar where gitcrypt.salt and
> gitcrypt.pass were stored in a gpg-encrypted file. After cloning, you
> decrypt once with gpg, then un-smudge all the encrypted files. No more gpg
> after that.

That's essentially how the GPG feature works.

git-crypt doesn't use anything called "gitcrypt.salt" or "gitcrypt.pass"
though - you might be confusing git-crypt with another project. (I may very
well end up renaming git-crypt - it's a way too generic name.)

~~~
sigil
_That 's essentially how the GPG feature works._

Cool. I think that's the way to go. If you needed GPG for things beyond the
initial checkout, automated git deploys (among other things) would be out of
the question.

 _You might be confusing git-crypt with another project._

Oh, wow, you're right. I'm using a forked version of something called git-
encrypt: [https://github.com/shadowhand/git-
encrypt](https://github.com/shadowhand/git-encrypt)

This is just a shell script (no compiled code), started about a year before
your git-crypt, but interestingly the design is very similar. Both of you are
using smudge and clean filters with AES 256.

------
xe4l
I evaluated git-crypt for a previous venture and ended up using gitolite hooks
instead. The setup I built stored users PGP Key ID, associated the Key ID with
their gitolite account and used hooks to encrypt content for users with
permission to the repo. A system account was created with a corresponding
keypair to handle user add/mod/del by decrypting and re-encrypting content for
the appropriate users in a given repo.

The beauty of this setup was, it was all over SSH and all keys used to access,
sign and encrypt content (included the system user) were stored on smart
cards.

If security is important, it's wise to take steps that align with or exceed
your risk appetite.

------
yepguy
Also check out git-remote-gcrypt for fully encrypted remotes.

[https://github.com/blake2-ppc/git-remote-
gcrypt](https://github.com/blake2-ppc/git-remote-gcrypt)

------
jyap
I wrote something which allows storing encrypted files in a Git repository.

The main difference is instead of encrypting a full file it uses a template
mechanism to encrypt just values. I wrote a quick start which covers it
further. I've been meaning to write a blog post which further explains the use
case with more details. Anyway, check it out here:

[https://github.com/jyap808/jaeger](https://github.com/jyap808/jaeger)

------
StavrosK
I use and recommend git-crypt. It's great when you need to version sensitive
files but don't want to give everyone access to them.

------
jrochkind1
A question I've had for a while: Is the nature of the cryptography in git-
crypt such that I could feel secure storing a few encrypted files including
passwords in a git with public access, such as a public github?

~~~
fat0wl
yea been wondering about this as well.. basically usage in general.

i've been thinking its a cheap-skate way to get private repos for free on
github... XD but really the ideal use case would be to be able to keep
passwords & sensitive info in the repo but have it make it to production
without having to manually re-config.

i'm assuming if you put the key on your webserver it would be able to do this?
also assuming you are on a service where you can actually access the
filesystem outside your repo

(o and the reason this relates to your comment being.... would be nice to have
it pass through github on way to prod. then it could be a nice dev+github+AWS
kindof deploy process)

~~~
jrochkind1
Yep, my use case is basically the same as yours.

I'm not just trying to score a free private repo, I actually want to share my
app code with others open source who would like to view it -- even though the
app itself is customized for our context, I don't mind letting people see it.

If you deploy your app with capistrano or similar automation, there are
various ways to handle deploy. Not neccesarily any need to access any file
systems, if you are deploying to heroku for instance, you might just need your
deploy tool to set heroku config/env variables.

Anyhow, as far as whether git-crypt is really designed for this use case, I'm
encouraged by a comment from the author here in this thread: "Where git-crypt
really shines is where most of your repo is public, but you have a few files
(perhaps private keys named *.key, or a file with API credentials) which you
need to encrypt." Where most of your repo is actually public, yep, but just a
file or two with credentials etc that need to be encrypted, yep! Okay, sweet.

------
rsync
Does git-crypt require a hook script of any kind on the server side ?

~~~
sigil
If you use bare repositories, no.

