From a72d345f9fd07b9878be09aea90ed53e2e2648c6923ac7fb9abc934daa31e72d Mon Sep 17 00:00:00 2001 From: Nicholas Johnson Date: Thu, 30 Nov 2023 00:00:00 +0000 Subject: Switch to the DiΓ‘taxis documentation approach MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HOWTO.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 78 ++++++++++++++++-------------------------------------------- REFERENCE.md | 30 +++++++++++++++++++++++ 3 files changed, 122 insertions(+), 57 deletions(-) create mode 100644 HOWTO.md create mode 100644 REFERENCE.md diff --git a/HOWTO.md b/HOWTO.md new file mode 100644 index 0000000..c926c2d --- /dev/null +++ b/HOWTO.md @@ -0,0 +1,71 @@ +# Git Privacy + +Follow the instructions in this document to obfuscate Git timestamps. + +## View Commit Timestamps + +To view commit timestamps, run: + +```sh +git log --format=fuller +``` + +## Obfuscate Timestamps for Commits and Annotated Tags + +For maximum privacy, set the author and committer dates to a clearly forged fixed date in UTC inside the interactive shell configuration: + +```sh +export GIT_AUTHOR_DATE="2000/01/01T00:00:00+0000" +export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" +``` + +To balance privacy and timestamp accuracy, set the author and committer dates to a course-grained date in UTC inside the interactive shell configuration: + +```sh +export GIT_AUTHOR_DATE="$(date -u +%DT00:00:00%z)" +export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" +``` + +Remember that shell environment variables do not change after being set, so dates update only after a new interactive shell is opened. + +## Obfuscate Timestamps for Digital Signatures + +For maximum privacy, create a custom version of GnuPG with a fixed timestamp set **between when the signing key was generated and the current date**: + +```sh +#!/bin/sh +gpg --faked-system-time ! $@ +``` + +See gpg(1) for valid `` formats. + +To balance privacy and timestamp accuracy, create a custom version of GnuPG with a course-grained timestamp in UTC set **after the signing key was generated**: + +```sh +#!/bin/sh +gpg --faked-system-time "$(date -u +%Y%m%dT000000)!" $@ +``` + +Set the script as executable: + +```sh +chmod +x /path/to/custom-gpg.sh +``` + +Tell Git to use the new script: + +```sh +git config --global gpg.program /path/to/custom-gpg.sh +``` + +## Forges + +To prevent forges from tracking Git push times, create a Cron job which pushes the repository at fixed intervals: + +```cron +0 6 * * * git -C /path/to/repo/ push origin master +``` + +## License + +This file is licensed under [CC-BY-SA 4.0](LICENSE). diff --git a/README.md b/README.md index 04942eb..affccef 100644 --- a/README.md +++ b/README.md @@ -1,78 +1,42 @@ -# Git-Privacy +# Git Privacy -## ❌ Default Git Privacy ❌ +This document is mainly concerned with *why* one would want to obfuscate Git timestamps. See [HOWTO.md](HOWTO.md) for instructions on *how* to obfuscate Git timestamps. See [REFERENCE.md](REFERENCE.md) for technical information about Git timestamps. -[Git is generally good about not preserving any metadata](https://git.wiki.kernel.org/index.php/ContentLimitations), except when it comes to timestamps. With only 3 commands, anyone can find out the time zones and exact clock times a developer makes commits. +## Why obfuscate Git timestamps? -```sh -git clone -cd -git log --format=fuller -``` +The following user stories illustrate why one might want to obfuscate Git timestamps: -This can leak personal information about a developer's life. The time zones reveal the developer's approximate location in the world and exact commit times recorded over a sufficient timespan may be used to deduce a developer's sleep patterns for example. +> "As a globetrotting remote contributor for a public codebase, I want to hide my timezone so that strangers on the internet don't know when I'm away from home." -## πŸ“… Git Timestamps πŸ“… +> "As a translator for a public codebase, I want to erase my timestamps so that I don't have to be creeped out that anybody can see exactly when I was working every day for the past ten years." -[Git commit objects](https://git-scm.com/docs/user-manual.html#commit-object) always have at least 2 timestamps. They are controlled by the following environment variables: +> "As a privacy-conscious maintainer for a public codebase, I want to avoid leaking the times when I'm working so that there's one less way for mass surveillance to track me." -* `GIT_AUTHOR_DATE` represents when the changes were made -* `GIT_COMMITTER_DATE` represents when the changes were committed +> "As a pseudonymous software developer for a controversial public codebase, I want to avoid leaking my timezone so that it's harder for technically-proficient adversaries to deanonymize me by correlating my timezone with other information." -Annotated [Git tag objects](https://git-scm.com/docs/user-manual.html#tag-object) always have at least 1 timestamp. It is also controlled by the `GIT_COMMITTER_DATE` environment variable. +## Why not obfuscate Git timestamps? -There is another timestamp which comes from the optional GnuPG signature on a commit or annotated tag. It is controlled by GnuPG. +There are reasons it might be a bad idea to obfuscate Git timestamps. -### ⚠ Warning ⚠ +### Functionality -Before you follow any of the steps below to obfuscate Git timestamps, be aware that it can cause certain features of Git to break in unexpected ways. The author takes no responsibility for any breakage that occurs. +Certain Git commands may not work as intended with obfuscated timestamps. -The author is not a lawyer and this is not legal advice, but obfuscating Git's timestamps may also result in more difficulty refuting copyright claims. The author takes no responsibility for this either. +**TODO**: -### Obfuscating Timestamps for Commits and Annotated Tags +* Investigate which commands are affected by timestamp obfuscation +* Investigate if Git ignores clearly forged timestamps -Git can't remove timestamps altogether, but the `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` environment variables can be set to any arbitrary date. Preferably, use dates from before Git was invented to clearly signal the timestamps are forged: +### Copyright -```sh -export GIT_AUTHOR_DATE="2000/01/01T00:00:00+0000" -export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" -``` +The author is not a lawyer and this is not legal advice. -To retain the day on which changes and commits are made, set `GIT_AUTHOR_DATE` and `GIT_COMMITTER_DATE` to the output of the date command, like so: +If the copyright holder of a piece of code is ever in dispute, having obfuscated Git timestamps could be disadvantageous to proving ownership of the code. Even with Git timestamps that are accurate to the nearest hour, the mere fact that they are manipulated could introduce skepticism about who holds the copyright. -```sh -export GIT_AUTHOR_DATE="$(date -u +%DT00:00:00%z)" -export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" -``` +## Why is timestamp obfuscation not an official feature of Git? -Environment variables don't change after being set, so the dates update when a new shell is opened, not at midnight. - -### πŸ”‘ Obfuscating Timestamps for Digital Signatures πŸ”‘ - -GnuPG can't remove its signature timestamps altogether, but they can be forged by configuring Git to run a custom version of GnuPG: - -```sh -#!/bin/sh -gpg --faked-system-time ! $@ -``` - -For GnuPG signatures with a fixed forged timestamp to be verifiable, `` must be manually set to a time between the expiry date of the signing key and when it was generated. See gpg(1) for how to format ``. - -To retain the day on which GnuPG signatures are made, use the output of the date command: - -```sh -#!/bin/sh -gpg --faked-system-time "$(date -u +%Y%m%dT000000)!" $@ -``` - -The last step is to set the script as executable with `chmod +x /path/to/custom-gpg.sh` and point Git to it with `git config --global gpg.program /path/to/custom-gpg.sh`. - -## πŸ“ Additional Notes πŸ“ - -Github is known to record [when commits are pushed](https://api.github.com/repos/cirosantilli/china-dictatorship/events). See the ticket about [Github contribution activity](https://github.com/isaacs/github/issues/142). To obfuscate push times, one could push code with cron at regular time intervals. - -It's possible to use Git hooks to accomplish timestamp obfuscation, but it's still necessary to manually override the date for some Git commands, making it very inconvenient. I asked Git developers to implement a timestamp privacy feature, but it was decided against. If you're curious why, here's [a writeup of the discussion](https://git.github.io/rev_news/2023/08/31/edition-102/#support) from the 102nd edition of Git Rev News. +The author [proposed](https://git.github.io/rev_news/2023/08/31/edition-102/#support "Git Rev News: Edition 102") adding a new timestamp obfuscation feature in Git, but for a variety of reasons Git maintainers were not convinced. ## License -This README file is licensed under [CC-BY-SA 4.0](LICENSE). +This file is licensed under [CC-BY-SA 4.0](LICENSE). diff --git a/REFERENCE.md b/REFERENCE.md new file mode 100644 index 0000000..e6d182f --- /dev/null +++ b/REFERENCE.md @@ -0,0 +1,30 @@ +# Git Privacy + +This document references all Git timestamps that pose a privacy concern. + +## Commit Object Timestamps + +[Git commit objects](https://git-scm.com/docs/user-manual.html#commit-object) always have at least 2 timestamps: + +* `GIT_AUTHOR_DATE` is the timestamp used for the "author" field. +* `GIT_COMMITTER_DATE` is the timestamp used for the "committer" field. + +## Annotated Tag Object Timestamps + +[Annotated Git tag objects](https://git-scm.com/docs/user-manual.html#tag-object) always have at least 1 timestamp: + +* `GIT_COMMITTER_DATE` is the timestamp used for the "committer" field. + +## GnuPG Signature Timestamps + +[GnuPG signatures](https://www.gnupg.org/gph/en/manual/x135.html) on signed commits and signed annotated tags include a timestamp. + +## Git Forges + +Some Git forges log and/or publicly reveal when commits are pushed. + +**TODO**: Investigate and document each forge's Git push logging. + +## License + +This file is licensed under [CC-BY-SA 4.0](LICENSE). -- cgit v1.2.3