Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add `del-gpg-user` to delete (and re-encrypt) repository #47

reedloden opened this issue Mar 25, 2015 · 31 comments

Add `del-gpg-user` to delete (and re-encrypt) repository #47

reedloden opened this issue Mar 25, 2015 · 31 comments


Copy link

@reedloden reedloden commented Mar 25, 2015

Need to be able to remove a GPG key for a user and then re-encrypt the repository. Obviously, the user would be able to decrypt old revisions but any new revisions would not be encrypted with the user's key.

Copy link

@dupuy dupuy commented Apr 7, 2015

This is definitely an issue that should also be addressed in the documentation - for security to be meaningful it is important for end-users to fully understand the security implications of the use of a tool - and even if there is a del-gpg-user subcommand that re-encrypts the repository, end users need to understand that they need to revoke and regenerate any credentials that were (ever) stored in the repository - and that is something that git-crypt cannot implement itself as revocation/regeneration is entirely outside the Git ecosystem.

Something that del-gpg-user could do to "help" or "encourage" such revocation/regeneration would be to replace all encrypted files with empty ones, but the implications of that need to be examined as it might just make things more confusing for less experienced users.

Perhaps rather than (or as a simpler step before) adding del-gpg-user a better approach might be to add a re-init command that just does the regeneration of encryption key (with optional removal of encrypted files and/or their contents).

Anyhow, I've no experience with Go, but can probably contribute to the documentation a section on the implications of putting credentials or other types of secrets in a git-crypt-enabled repository, and what revocation of access may mean - I'll look at what I could do and try to submit a PR with an outline sometime next week.

Copy link

@AGWA AGWA commented Apr 8, 2015

This issue has been on my radar for a while. It's surprisingly complicated, because you have to rotate git-crypt's internal symmetric key and re-encrypt all files with the new symmetric key, in order to preserve confidentiality of future commits. To avoid breaking history, you have to keep around the old versions of the key and use them when dealing with old commits. Fortunately, git-crypt already has the framework for this - it just needs to be wired up, and tested extensively. I suspect that there will be big problems with merging if the key has been rotated on one branch of the merge. So, a lot of the work will be testing how key rotation interacts with various other Git operations. Fortunately, that's something anyone can help with, without having to do any coding.

@dupey you are correct about credentials protected by git-crypt needing to be rotated too, but that's definitely outside the domain of git-crypt, and I don't like the idea of git-crypt automatically truncating files. A discussion in the documentation would definitely be warranted though. Thanks for offering to help with this.

Copy link

@erikthorselius erikthorselius commented May 11, 2015


1 similar comment
Copy link

@alexkli alexkli commented May 16, 2015


Copy link

@redterror redterror commented May 19, 2015

Just curious - what are the use cases people have in mind for this feature? I had convinced myself I needed it if I wanted to revoke access from a former employee, but after thinking some more, I don't actually need it. In my situation github's access controls + secret rotation are sufficient.

Copy link

@reedloden reedloden commented May 20, 2015

@redterror git-crypt supports two forms of encryption -- symmetric key and GPG. In the former case (which it sounds like you use), rotation of the key is all you can do. In the latter, you need to be able to remove a user's GPG public key and re-encrypt the entire repository. The user would be able to access old copies of the repository that were encrypted with his/her public key, but any new changes would not be encrypted with his/her GPG public key, so they would be inaccessible.

Copy link

@dupuy dupuy commented May 20, 2015

@reedloden Technically, a symmetric key is used for encryption of files in every case - it is just that in the second case the symmetric key itself is encrypted with one or more GPG keys and those copies of the encrypted key are committed to the repository, allowing a user whose GPG key was "added" to decrypt the encrypted contents in the repository using nothing more than their private key and the repository itself.

Copy link

@redterror redterror commented May 20, 2015

@dupuy - I'm with you on all that, what I was suggesting was that the use-case of a privileged user that becomes unprivileged but still retains repo access at all may be uncommon. In my case removing access at the github level solves the problem entirely.

I get that this is useful out of completeness, it just seems like a scenario that folks may think they need but actually don't. I don't know really know, I'm just suggesting that this may not be all that important in real deployments.

pfalcon added a commit to pfalcon/git-crypt that referenced this issue Dec 1, 2015
Perpetual grant of access is certainly a security issue, so goes to
the corresponding section. Based on the discussion in
Copy link

@pfalcon pfalcon commented Dec 1, 2015

With the thoughts in #23 (comment) , I'd like to make a step forward with further progressing git-crypt, by making it be fair about its deficiencies: #72

Copy link

@geowa4 geowa4 commented Dec 17, 2015

This would be a nice feature. I had to jump through some interesting hoops to re-initialize the repo after a coworker left. For my use case, I don't really care about history; the value of the old database password isn't exactly useful.

Copy link

@phunehehe phunehehe commented Apr 21, 2016

So here's what I did to re-encrypt files to remove a user:

  • Make a backup (with decrypted files): cp -r . /path/to/backup
  • Save a list of files that are encrypted: git crypt status | grep -v 'not encrypted' > ../encrypted-files.txt
  • Make git-crypt forget about itself: rm .git-crypt
  • Delete the encrypted files: awk '{print $2}' ../encrypted-files.txt | xargs rm
  • Commit (at this point you get a repo without git-crypt stuff)
  • Add git-crypt from scratch (init and add-gpg-user)
  • Copy the decrypted files from the backup: awk '{print $2}' ../encrypted-files.txt | while read l; do cp /path/to/backup/$l $l; done
  • Commit (at this point you are done, but be sure to verify things are properly encrypted before publishing)

Hope that help until we get there 😅

Copy link

@TiagoTT TiagoTT commented Apr 21, 2016

I have a suggestion for the implementation that may work.

  • Each encrypted file would include the encryption key name in its header metadata.
  • git-crypt unlock would be able to load multiple git-crypt secret keys into .git/git-crypt/keys.
  • git-crypt would use the right key to decrypt each file automatically based on the header metadata.
  • .gitattributes would be checked only for encryption rules, but not for decryption anymore.

It might be possible to use the existing support for multiple keys to achieve the desired user access revocation (for the future commits only of course).

Consider the following steps:

  • Create new key: git-crypt init -k A.
  • Add all users except the one to remove to the new key: git-crypt add-gpg-user -k A user.
  • Swap the new key A with the default key.

All new or updated files would be encrypted with the new default key.
All old files would be decrypted with the old key.

Would this work?

Copy link

@glogiotatidis glogiotatidis commented May 24, 2016

Based on phunehehe's comment I hacked together a script to get the job done. You can find it here

Copy link

@tgjamin tgjamin commented Mar 23, 2017

Any updates on this?

Copy link

@voltechs voltechs commented Apr 14, 2017

Any thoughts on using the oft-misunderstood-and-avoided-but-very-powerful-and-actually-not-scary-at-all feature git rebase for when a user is removed?

Copy link

@VanAxe VanAxe commented May 15, 2017

I'd like to poke the proverbial bear.

Bump. 😈

Copy link

@avanier avanier commented Aug 1, 2017

For some odd reason, I now need this feature. 😛


Copy link

@inhumantsar inhumantsar commented Oct 26, 2017


Copy link

@inhumantsar inhumantsar commented Oct 28, 2017

I wrote a bash script that will rekey the repo on-demand using a remote list of users (currently, JSON in S3).

Use git-crypt-team -e to edit the user file and upload it to S3. It should be formatted like [{"key": "KEYID123", ...}, ...]. You can include any additional attributes with each key, but only key is required. Then run git-crypt-team -r to re-encrypt everything using the current team list in S3.

The script will take care of getting GPG keys from public sources, signing them, backing up and restoring encrypted files, plus all of the cleanup, init, and git work required. It even does it all in a branch, if things go wrong just run git reset --hard HEAD && git checkout master.

Copy link

@Constantin07 Constantin07 commented Mar 9, 2018

I also need this feature - be able to revoke access to encrypted files.
Another thing which is not quite clear to me is how to get the list already added users ? so that we know which GPG key to delete ...

Copy link

@nthypes nthypes commented Mar 11, 2018

So, what is the best approach ? Use symmetric key and rotate?

Copy link

@shazChaudhry shazChaudhry commented Mar 17, 2018

I am also interested in what the recommended approach is.

Copy link

@vonglasow vonglasow commented Mar 23, 2018

I have seen this gist from @glogiotatidis do we have another approach to remove GPG key added ?

Copy link

@glogiotatidis glogiotatidis commented Mar 23, 2018

I have seen this gist from @glogiotatidis do we have another approach to remove GPG key added ?

slightly off-topic but since i'm mentioned: For new repos we have experimenting with keybase's encrypted git and teams and so far works OK.

Copy link

@vonglasow vonglasow commented Mar 26, 2018

@glogiotatidis thanks for the feedback

Copy link

@ip1981 ip1981 commented May 2, 2019

I found simpler way to rotate the key. Simpler as in "closer to the basics" :).

  1. Unlock the repository (git-crypt unlock).
  2. Replace .git/git-crypt/keys/default (see below).
  3. At this moment Git will show that your encrypted files are modified.
  4. Remove .git-crypt/keys/default/0/*.gpg.
  5. Add new users in the normal way (git-crypt add-gpg-user ...).
  6. Commit these changes (prefer to amend the commit made by git-crypt add-gpg-user ...)

About .git/git-crypt/keys/default:

This is the key used by git-crypt to encrypt files. This file only exist after you execute git-crypt unlock. This file is secret! This file is also encrypted for each user as .git-crypt/keys/default/0/*.gpg and commited to the Git history. You can compare git/git-crypt/keys/default and .git-crypt/keys/default/0/<you-gpg-key>.gpg (with gpg -d ...).

How to get a new .git/git-crypt/keys/default? When the repository is locked, execute git-crypt init and save the new key somewhere (otherwise it will be overwritten on git-crypt unlock) :)

P. S. Or better use another empty repository for a new encryption key.

Copy link

@tobega tobega commented May 16, 2019

FWIW, I found a procedure to rotate the symmetric key that doesn't need poking at hidden git-crypt dependent files:

  1. Delete .gitattributes files. This will unencrypt your secrets.
  2. Stash the changes (to store the unencrypted secrets locally)
  3. Delete .gitattributes and all your secrets files.
  4. Commit. (operation 2+3 are so as you don't have to commit any plaintext secrets)
  5. do 'git-crypt lock' which in this instance just throws away your key
  6. do 'git-crypt init' to create a new key.
  7. Unstash the stashed files and recreate .gitattributes
  8. commit
    Note that collaborators need to do 'git-crypt lock' before pulling the new changes in order to throw away the old key and work with just text files in plain git mode (although the secrets are encrypted still).

After updating, just git-crypt unlock with the new key.

Copy link

@Falkor Falkor commented Sep 20, 2019

I reworked a little the script made by @glogiotatidis from the initial proposal of @phunehehe (for endling the case of absence of encrypted files, expired keys etc.). The resulting extended version is available on

xihh87 added a commit to xihh87/git-crypt-test that referenced this issue Nov 22, 2019
# Dejar los secretos en claro antes de realizar el proceso
git crypt unlock
# Eliminar el acceso a la clave con mi llave privada.
git rm .git-crypt/keys/default/0/0EF5D686FC13831A54874C275FC681B4822DABB0.gpg
# Eliminar la clave simétrica con la que se está cifrando la información.
rm .git/git-crypt/keys/default
# Hacer commit hasta ahora
git commit
# Cambiar los secretos en los archivos privados.
$EDITOR secreto
# Generar una nueva clave de cifrado
git crypt init
# Agregar a las personas que necesitan agregarse
for key in key1 key2 key3; do
  git crypt add-gpg-user $key

# La persona que recibe el código debe bloquear el repositorio [1]
git crypt lock
git pull

[1]: AGWA/git-crypt#47
Copy link

@thomsh thomsh commented Mar 11, 2020

I rework @Falkor rework to make the script safer, compliant with shellcheck:
Note that @Falkor version works on my simple repository, few files, no space or special char in filenames
[Reminder]: As said previously a couple of times, this script only rotate key for future commit, git history is not rewritten at all.
If you protect few secret in your repository, change them after rotating the git-crypt key

Copy link

@Falkor Falkor commented Mar 11, 2020

@thomsh Many thanks for the rework! I merged your contributions into my gist.

Copy link

@bartv2 bartv2 commented Mar 11, 2020

I created a script that only updates the key and the encrypted files. This should be used after removing 1 or more collaborators gpg files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet