git privacy

Let’s say you want to work on a public git repo without revealing your identity.

The real solution is to set up a new computer on a VPN (so you don’t reveal your IP address to the git hosting service) set to a different time zone (so you don’t publish that you’re even in the same general area) with separate git credentials and keys entirely. Make sure you secure the privacy of your anonymous email address, in case it could somehow be correlated to you. Don’t cross-contaminate between your normal coding box and your anonymous box. You’ll probably also want to randomize the timestamps (don’t forget author and committer) so nobody can analyze when you’re awake and deduce a probable location.

But that’s a lot of work.

You can accomplish most of the same thing with a VM on your normal box, but there’s a higher risk of cross-contamination since you’re on the same IP by default, and active on the network at the same times. You also run the risk of potentially sharing files from your main box to your anonymous VM, which could lead to a mistake.

That’s also a lot of work.

If you don’t mind the very likely possibility of errors leading to your potential de-anonymization, then here’s one way to be “anonymous enough” for some purposes. (Until you make a mistake, and the party’s over.)

Since git doesn’t support .gitconfigs in parent directories, you can’t just set a file in the parent of your anonymous checkouts and forget about it. Even if you could, you might still want to use a different time zone from your usual identity, so there’s one less clue. Plus, how would you cleanly separate your normal identity from your secret identity on your git hosting service, when you don’t always control the user you use for ssh access (e.g. github has everyone ssh as git).

You need a way to set your git name and email address for every repo you want to work on anonymously, plus some automated help keeping your identity from leaking.

Try this git clone replacement. The only trick is remembering to use it–maybe make a parent folder for all your anonymous work and throw it in there named something like OH-GOD-DONT-REGULAR-GIT-CLONE--USE-ME-INSTEAD so at least when you ls before a clone you’re likely to be reminded. You’ll also need some ssh config, below.

Before I explain, here’s the required ~/.ssh/config change. You’ll of course need to generate your ~/.ssh/id_rsa-github-private key in addition. This all needs to be in place before running the script.

Host github.private
	HostName github.com
	User git
	IdentityFile ~/.ssh/id_rsa-github-private

The clone script does a few things. First, it rewrites the clone URL (which is required to be like git@github.com..., though it wouldn’t be hard to support other services too) to a made-up host github.private. The ssh config reroutes all ssh requests at github.private to the right place, with your special private github key. This is how you can keep your private ssh identity separate from your normal one, on the same box.

Then it makes a new git template directory with the default contents plus a fancy post-commit hook. The hook checks the commit-in-progress for the specific private name/email address you want to use, and that the timestamps are in UTC, rewriting it if necessary.

Finally, it does the clone, also setting up its config so at least your name and email address are protected even if you evade the post-commit hook.

Speaking of: one downside is that rebasing becomes a huge pain, if you care about UTC timestamps. Without extra work, it’ll rewrite the commit time (but not author time) in your normal time zone. Luckily, there is a solution, but it’s also a lot of work (see my above points about doing anonymous git the right way), so my recommendation is to just not rebase.

It’s not perfect, but sometimes, it’s good enough.