Skip to content

Instantly share code, notes, and snippets.

@Falkor
Forked from glogiotatidis/remove-gpg-user.sh
Last active April 8, 2025 08:04
Show Gist options
  • Save Falkor/7b29f16f5f79404fe41476be0d992783 to your computer and use it in GitHub Desktop.
Save Falkor/7b29f16f5f79404fe41476be0d992783 to your computer and use it in GitHub Desktop.

Revisions

  1. Sebastien Varrette revised this gist Apr 15, 2020. 1 changed file with 33 additions and 20 deletions.
    53 changes: 33 additions & 20 deletions git-crypt-rm-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -20,6 +20,18 @@
    # git checkout -b git-crypt-remove
    # git-crypt-rm-gpg-user.sh -l # List configured GPG keys
    # git-crypt-rm-gpg-user.sh -r <KEYID>
    # git push origin git-crypt-remove # publish the branch
    #
    # Merge (sync with your collaborators for the appropriate timing):
    # git checkout master # or devel or whatever main branch
    # git-crypt lock
    # git merge git-crypt-remove
    # # release the repository
    #
    # Pulling for your collaborators
    # cd /path/to/protected/repo
    # git-crypt lock
    # git pull origin
    #
    # You can check the full, 64-bit (8-byte) key ID for a key within your keyring with
    # gpg -k [email | pattern]
    @@ -41,11 +53,12 @@ set -eo pipefail

    KEY_TO_REMOVE=
    KEY_FINGERPRINT=
    # CMD_PREFIX=

    # HELPERS
    print_error_and_exit () {
    echo "*** ERROR *** $*"
    echo "Usage: see 'git-crypt-rm-gpg-user.sh -h'"
    echo "Usage: see '$(basename $0) -h'"
    exit 1
    }

    @@ -60,7 +73,7 @@ really_continue() {

    print_usage () {
    cat <<EOF
    Remove a given GPG key from a git-crypt enabled repository.
    $(basename $0): Remove a given GPG key from a git-crypt enabled repository.
    Options:
    -l : list GPG keys configured within git-crypt
    @@ -70,8 +83,8 @@ Typical workflow:
    cd /path/to/protected/repo
    git checkout -b git-crypt-remove
    git-crypt-rm-gpg-user.sh -l # List configured GPG keys
    git-crypt-rm-gpg-user.sh -r <KEYID>
    $(basename $0) -l # List configured GPG keys
    $(basename $0) -r <KEYID>
    You can check the full, 64-bit (8-byte) key ID for a key within your keyring with
    gpg -k [email | pattern]
    @@ -119,6 +132,7 @@ while [ $# -ge 1 ]; do
    -h | --help) print_usage; exit 0;;
    -l | --list) list_git_crypt_keys; exit 0;;
    -r | --remove) shift; KEY_TO_REMOVE=$1;;
    # -n | --dry-run) CMD_PREFIX=echo ;;
    esac
    shift
    done
    @@ -164,8 +178,9 @@ git stash # stash potential typechange
    # Remove encrypted files and git-crypt
    git crypt status -e |sed -E 's/^\s+encrypted: //g' > "${TMPFILE}"
    if [ -s "${TMPFILE}" ]; then
    xargs -I {} -- rm -- {} < "${TMPFILE}"
    git commit -a -m "Remove encrypted files"
    awk '{print $2}' ${TMPFILE} | xargs rm
    #xargs -I {} -- rm -- {} < "${TMPFILE}"
    git commit -a -m "Remove encrypted files"
    fi
    rm -rf -- .git-crypt
    git commit -m "Remove git-crypt (in particular configuration related to key ${KEY_TO_REMOVE})" .git-crypt
    @@ -175,7 +190,7 @@ rm -rf .git/git-crypt
    git crypt init

    # Add existing users, except the key to remove
    find "$CURRENT_DIR/.git-crypt/keys/default/0" -type f -iname '*gpg' -print|while read -r keyfilename
    find "${CURRENT_DIR}/.git-crypt/keys/default/0" -type f -iname '*gpg' -print|while read -r keyfilename
    do
    basename="$(basename "$keyfilename")"
    key="${basename%.*}"
    @@ -195,22 +210,20 @@ do
    git crypt add-gpg-user "$key"
    done

    cd "$CURRENT_DIR"
    while read -r line
    do
    rsync -rp -R "${line}" "$TMPDIR/$BASENAME"
    done < "${TMPDIR}/${BASENAME}/${TMPFILE}"
    cd "${CURRENT_DIR}"
    for encrypted_file in $(awk '{print $2}' ${TMPDIR}/${BASENAME}/${TMPFILE}); do
    rsync -rp -R "${encrypted_file}" "${TMPDIR}/${BASENAME}"
    done

    cd "$TMPDIR/$BASENAME"
    while read -r line
    do
    git add "$line"
    done < "${TMPDIR}/${BASENAME}/${TMPFILE}"
    cd "${TMPDIR}/${BASENAME}"
    for encrypted_file in $(awk '{print $2}' ${TMPFILE}); do
    git add "${encrypted_file}"
    done

    git commit -m "New encrypted files"
    git commit -m "New encrypted files" || true
    popd

    git crypt lock
    git pull "$TMPDIR/$BASENAME"
    git pull "${TMPDIR}/${BASENAME}"

    rm -rf -- "$TMPDIR"
    rm -rf -- "${TMPDIR}"
  2. Sebastien Varrette revised this gist Mar 11, 2020. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions git-crypt-rm-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -18,8 +18,8 @@
    #
    # cd /path/to/protected/repo
    # git checkout -b git-crypt-remove
    # git-crypt-rm-gpg-user.sh $0) -l # List configured GPG keys
    # git-crypt-rm-gpg-user.sh $0) -r <KEYID>
    # git-crypt-rm-gpg-user.sh -l # List configured GPG keys
    # git-crypt-rm-gpg-user.sh -r <KEYID>
    #
    # You can check the full, 64-bit (8-byte) key ID for a key within your keyring with
    # gpg -k [email | pattern]
    @@ -133,7 +133,7 @@ if [ -z "${KEY_FINGERPRINT:-}" ]; then
    print_error_and_exit "Unable to retrieve key fingerprint"
    fi

    if [ -z "$(command -v rsync)" ];then
    if [ -z "$(command -v rsync)" ]; then
    print_error_and_exit "This script use rsync, sadly rsync is not found on your system"
    fi

  3. @thomsh thomsh revised this gist Mar 11, 2020. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion git-crypt-rm-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -30,11 +30,12 @@
    # all down to one.
    #
    # Based on https://github.com/AGWA/git-crypt/issues/47#issuecomment-212734882
    # and https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    #
    #
    # GIST source https://gist.github.com/glogiotatidis/e0ab45ed5575a9d7973390dace0552b0
    # amended to work on Mac OS and with cosmetic changes for a more convenient interface in
    # https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    # Script is now shellcheck compliant and safer: https://gist.github.com/thomsh/ed14fa82cf43a6b283c1eea9574fb76e
    #################
    set -eo pipefail

  4. @thomsh thomsh revised this gist Mar 11, 2020. 1 changed file with 10 additions and 5 deletions.
    15 changes: 10 additions & 5 deletions git-crypt-rm-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    #!/bin/bash
    #!/usr/bin/env bash
    #
    # Script to remove GPG key from git-crypt
    # Script to remove GPG user (recipient) with git-crypt
    #
    # It will re-initialize git-crypt for the repository and re-add all keys except
    # the one requested for removal.
    @@ -9,9 +9,9 @@
    # Removing a user will prevent them from reading future changes but they will
    # still have a copy of the data up to the point of their removal.
    #
    # Usage: see 'remove-gpg-user.sh -h'
    # remove-gpg-user.sh -l : list GPG keys configured within git-crypt for the current directory
    # remove-gpg-user.sh -r <FULL-GPG-FINGERPRINT> : remove specified key from git-crypt configuration
    # Usage: see 'git-crypt-rm-gpg-user.sh -h'
    # git-crypt-rm-gpg-user.sh -l : list GPG keys configured within git-crypt for the current directory
    # git-crypt-rm-gpg-user.sh -r <FULL-GPG-FINGERPRINT> : remove specified key from git-crypt configuration
    # Ex: remove-gpg-user.sh -r 3BC18383F838C0B815B961480F8CAF5467D
    #
    # Typical workflow (assuming the script is placed in ~/bin/) :
    @@ -30,6 +30,7 @@
    # all down to one.
    #
    # Based on https://github.com/AGWA/git-crypt/issues/47#issuecomment-212734882
    # and https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    #
    # GIST source https://gist.github.com/glogiotatidis/e0ab45ed5575a9d7973390dace0552b0
    # amended to work on Mac OS and with cosmetic changes for a more convenient interface in
    @@ -131,6 +132,10 @@ if [ -z "${KEY_FINGERPRINT:-}" ]; then
    print_error_and_exit "Unable to retrieve key fingerprint"
    fi

    if [ -z "$(command -v rsync)" ];then
    print_error_and_exit "This script use rsync, sadly rsync is not found on your system"
    fi

    really_continue "About to remove the GPG Key ID ${KEY_TO_REMOVE} from Git-crypt configuration"

    set -x # enable debug just in case we need to dig
  5. @thomsh thomsh renamed this gist Mar 11, 2020. 1 changed file with 83 additions and 64 deletions.
    147 changes: 83 additions & 64 deletions remove-gpg-user.sh → git-crypt-rm-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -18,8 +18,8 @@
    #
    # cd /path/to/protected/repo
    # git checkout -b git-crypt-remove
    # ~/bin/$(basename $0) -l # List configured GPG keys
    # ~/bin/$(basename $0) -r <KEYID>
    # git-crypt-rm-gpg-user.sh $0) -l # List configured GPG keys
    # git-crypt-rm-gpg-user.sh $0) -r <KEYID>
    #
    # You can check the full, 64-bit (8-byte) key ID for a key within your keyring with
    # gpg -k [email | pattern]
    @@ -39,35 +39,41 @@ set -eo pipefail

    KEY_TO_REMOVE=
    KEY_FINGERPRINT=
    CMD_PREFIX=

    ###############
    print_error_and_exit() { echo -e "*** ERROR *** $*\n Usage: see '$(basename $0) -h'"; exit 1; }
    # HELPERS
    print_error_and_exit () {
    echo "*** ERROR *** $*"
    echo "Usage: see 'git-crypt-rm-gpg-user.sh -h'"
    exit 1
    }

    really_continue() {
    echo -n -e "/!\\ WARNING: $*\n Are you sure you want to continue? [Y|n]"
    read ans
    echo "/!\\ WARNING: $*"
    echo "Are you sure you want to continue? [Y|n]"
    read -r ans
    case $ans in
    n*|N*) exit 1;;
    esac
    }
    print_usage() {

    print_usage () {
    cat <<EOF
    Remove a given GPG key from a git-crypt enabled repository.
    Usage:
    $(basename $0) -l : list GPG keys configured within git-crypt
    $(basename $0) [-n] -r <FULL-GPG-FINGERPRINT> : remove key from git-crypt configuration
    Options:
    -l : list GPG keys configured within git-crypt
    [-n] -r <FULL-GPG-FINGERPRINT> : remove key from git-crypt configuration
    Typical workflow:
    cd /path/to/protected/repo
    git checkout -b git-crypt-remove
    ~/bin/$(basename $0) -l # List configured GPG keys
    ~/bin/$(basename $0) -r <KEYID>
    git-crypt-rm-gpg-user.sh -l # List configured GPG keys
    git-crypt-rm-gpg-user.sh -r <KEYID>
    You can check the full, 64-bit (8-byte) key ID for a key within your keyring with
    gpg -k [email | pattern]
    gpg -k --with-colons [email | pattern | id] | awk -F: '/^pub:/ { print $5 }'
    gpg -k --with-colons [email | pattern | id] | awk -F: '/^pub:/ { print \$5 }'
    See https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
    EOF
    @@ -77,14 +83,17 @@ EOF
    # Print info for a given key from your keyring
    ##
    print_key_info() {
    [ -z "$1" ] && print_error_and_exit "[$FUNCNAME] missing text argument"
    local key=$1
    local gpgid=$(gpg --list-keys --with-colons $key | awk -F: '/^pub:/ { print $5 }')
    local fpr=$(gpg -k --with-colons $key | awk -F: '/^fpr:/ { print $10; exit; }') # Only first fpr
    [ -z "${1:-}" ] && print_error_and_exit "${FUNCNAME[0]} missing text argument"
    local key
    local gpgid
    local fpr
    key="$1"
    gpgid="$(gpg --list-keys --with-colons "${key}" | awk -F: '/^pub:/ { print $5 }')"
    fpr="$(gpg -k --with-colons "${key}" | awk -F: '/^fpr:/ { print $10; exit; }')" # Only first fpr
    echo "==== Key Fingerprint: ${fpr} ==="
    echo "==== Long GPG ID: ${gpgid}"
    gpg --list-key "$key" || print_error_and_exit "Couldn't find info about $key"
    export KEY_FINGERPRINT=$fpr
    export KEY_FINGERPRINT="$fpr"
    }

    ###
    @@ -93,7 +102,7 @@ print_key_info() {
    list_git_crypt_keys() {
    for f in .git-crypt/keys/default/0/*.gpg; do
    # key="$(basename "${f}" .gpg)"
    print_key_info $(basename "${f}" .gpg)
    print_key_info "$(basename "${f}" .gpg)"
    # gpgid=$(gpg --list-keys --with-colons $key | awk -F: '/^pub:/ { print $5 }')
    # echo "==== Key Fingerprint: ${key} ==="
    # echo "==== Long GPG ID: ${gpgid}"
    @@ -108,21 +117,29 @@ while [ $# -ge 1 ]; do
    -h | --help) print_usage; exit 0;;
    -l | --list) list_git_crypt_keys; exit 0;;
    -r | --remove) shift; KEY_TO_REMOVE=$1;;
    # -n | --dry-run) CMD_PREFIX=echo ;;
    esac
    shift
    done

    [ -z "${KEY_TO_REMOVE}" ] && print_error_and_exit "No key to remove has been indicated"
    if [ -z "${KEY_TO_REMOVE:-}" ];then
    print_error_and_exit "No key to remove has been indicated"
    fi

    print_key_info "${KEY_TO_REMOVE}"
    [ -z "${KEY_FINGERPRINT}" ] && print_error_and_exit "Unable to retrieve key fingerprint"

    if [ -z "${KEY_FINGERPRINT:-}" ]; then
    print_error_and_exit "Unable to retrieve key fingerprint"
    fi

    really_continue "About to remove the GPG Key ID ${KEY_TO_REMOVE} from Git-crypt configuration"

    set -x # enable debug just in case we need to dig
    set -euo pipefail # enforce mode with nounset (-u)

    # Below code adapted from @glogiotatidis - https://gist.github.com/glogiotatidis/e0ab45ed5575a9d7973390dace0552b0
    TMPDIR=$(mktemp -d)
    CURRENT_DIR=$(git rev-parse --show-toplevel)
    BASENAME=$(basename `pwd`)
    TMPDIR="$(mktemp -d)"
    CURRENT_DIR="$(git rev-parse --show-toplevel)"
    BASENAME="$(basename "$(pwd)")"
    TMPFILE=list-encrypted-files.txt

    cat <<EOF
    @@ -133,59 +150,61 @@ EOF
    git crypt unlock

    # Work on copy.
    cp -rp $(pwd) $TMPDIR || true
    cp -a -- "$(pwd)" "$TMPDIR"

    pushd $TMPDIR/$BASENAME
    git stash # stash potential typechange
    # git status
    pushd "$TMPDIR/$BASENAME"
    git stash # stash potential typechange

    # Remove encrypted files and git-crypt
    git crypt status -e > ${TMPFILE}
    git crypt status -e |sed -E 's/^\s+encrypted: //g' > "${TMPFILE}"
    if [ -s "${TMPFILE}" ]; then
    awk '{print $2}' ${TMPFILE} | xargs rm
    git commit -a -m "Remove encrypted files"
    xargs -I {} -- rm -- {} < "${TMPFILE}"
    git commit -a -m "Remove encrypted files"
    fi
    rm -rf .git-crypt
    rm -rf -- .git-crypt
    git commit -m "Remove git-crypt (in particular configuration related to key ${KEY_TO_REMOVE})" .git-crypt
    rm -rf .git/git-crypt

    # Re-initialize git crypt
    git crypt init

    # Add existing users, except the key to remove
    for keyfilename in `ls $CURRENT_DIR/.git-crypt/keys/default/0/*gpg`; do
    basename=`basename $keyfilename`
    key=${basename%.*}
    if [[ $key == $KEY_FINGERPRINT ]]; then
    echo "ignoring key ${KEY_FINGERPRINT} to be removed"
    continue;
    fi
    # check if the key is expired - second field is 'e'
    # See https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
    expired="$(gpg --with-colons --list-keys --with-fingerprint $key | awk -F: '/^pub:/ { print $2; }')"
    if [[ "${expired}" == "e" ]]; then
    echo "/!\\ WARNING: key $key expired thus not integrated in the git-crypt keyring"
    echo "/!\\ WARNING: key details: "
    print_key_info $key
    continue
    fi
    git crypt add-gpg-user $key
    find "$CURRENT_DIR/.git-crypt/keys/default/0" -type f -iname '*gpg' -print|while read -r keyfilename
    do
    basename="$(basename "$keyfilename")"
    key="${basename%.*}"
    if [[ "$key" == "$KEY_FINGERPRINT" ]]; then
    echo "ignoring key ${KEY_FINGERPRINT} to be removed"
    continue
    fi
    # check if the key is expired - second field is 'e'
    # See https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
    expired="$(gpg --with-colons --list-keys --with-fingerprint "$key" | awk -F: '/^pub:/ { print $2; }')"
    if [[ "${expired}" == "e" ]]; then
    echo "/!\\ WARNING: key $key expired thus not integrated in the git-crypt keyring"
    echo "/!\\ WARNING: key details: "
    print_key_info "$key"
    continue
    fi
    git crypt add-gpg-user "$key"
    done

    cd $CURRENT_DIR
    for i in `awk '{print $2}' ${TMPDIR}/${BASENAME}/${TMPFILE}`; do
    #cp -rp --parents $i $TMPDIR/$BASENAME;
    #gcp -rp --parents $i $TMPDIR/$BASENAME;
    rsync -rp -R $i $TMPDIR/$BASENAME;
    done
    cd $TMPDIR/$BASENAME
    for i in `awk '{print $2}' ${TMPFILE}`; do
    git add $i
    done
    git commit -m "New encrypted files" || true
    cd "$CURRENT_DIR"
    while read -r line
    do
    rsync -rp -R "${line}" "$TMPDIR/$BASENAME"
    done < "${TMPDIR}/${BASENAME}/${TMPFILE}"

    cd "$TMPDIR/$BASENAME"
    while read -r line
    do
    git add "$line"
    done < "${TMPDIR}/${BASENAME}/${TMPFILE}"

    git commit -m "New encrypted files"
    popd

    git crypt lock
    git pull $TMPDIR/$BASENAME
    git pull "$TMPDIR/$BASENAME"

    rm -rf $TMPDIR
    rm -rf -- "$TMPDIR"
  6. Sebastien Varrette revised this gist Sep 19, 2019. 1 changed file with 16 additions and 1 deletion.
    17 changes: 16 additions & 1 deletion remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -21,6 +21,11 @@
    # ~/bin/$(basename $0) -l # List configured GPG keys
    # ~/bin/$(basename $0) -r <KEYID>
    #
    # You can check the full, 64-bit (8-byte) key ID for a key within your keyring with
    # gpg -k [email | pattern]
    # gpg -k --with-colons [email | pattern | id] | awk -F: '/^pub:/ { print $5 }'
    # See https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
    #
    # The script will create multiple commits to your repo. Feel free to squash them
    # all down to one.
    #
    @@ -64,6 +69,7 @@ You can check the full, 64-bit (8-byte) key ID for a key within your keyring wit
    gpg -k [email | pattern]
    gpg -k --with-colons [email | pattern | id] | awk -F: '/^pub:/ { print $5 }'
    See https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
    EOF
    }

    @@ -146,14 +152,23 @@ rm -rf .git/git-crypt
    # Re-initialize git crypt
    git crypt init

    # Add existing users, except the
    # Add existing users, except the key to remove
    for keyfilename in `ls $CURRENT_DIR/.git-crypt/keys/default/0/*gpg`; do
    basename=`basename $keyfilename`
    key=${basename%.*}
    if [[ $key == $KEY_FINGERPRINT ]]; then
    echo "ignoring key ${KEY_FINGERPRINT} to be removed"
    continue;
    fi
    # check if the key is expired - second field is 'e'
    # See https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=blob_plain;f=doc/DETAILS
    expired="$(gpg --with-colons --list-keys --with-fingerprint $key | awk -F: '/^pub:/ { print $2; }')"
    if [[ "${expired}" == "e" ]]; then
    echo "/!\\ WARNING: key $key expired thus not integrated in the git-crypt keyring"
    echo "/!\\ WARNING: key details: "
    print_key_info $key
    continue
    fi
    git crypt add-gpg-user $key
    done

  7. Sebastien Varrette revised this gist Sep 19, 2019. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -130,6 +130,7 @@ git crypt unlock
    cp -rp $(pwd) $TMPDIR || true

    pushd $TMPDIR/$BASENAME
    git stash # stash potential typechange
    # git status

    # Remove encrypted files and git-crypt
  8. Sebastien Varrette revised this gist Sep 18, 2019. 1 changed file with 11 additions and 7 deletions.
    18 changes: 11 additions & 7 deletions remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,7 @@
    # amended to work on Mac OS and with cosmetic changes for a more convenient interface in
    # https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    #################
    # set -eo pipefail
    set -eo pipefail

    KEY_TO_REMOVE=
    KEY_FINGERPRINT=
    @@ -127,16 +127,19 @@ EOF
    git crypt unlock

    # Work on copy.
    cp -rp $(pwd) $TMPDIR
    cp -rp $(pwd) $TMPDIR || true

    pushd $TMPDIR/$BASENAME
    # git status

    # Remove encrypted files and git-crypt
    git crypt status | grep -v "not encrypted" > ${TMPFILE}
    awk '{print $2}' ${TMPFILE} | xargs rm
    git commit -a -m "Remove encrypted files"
    git crypt status -e > ${TMPFILE}
    if [ -s "${TMPFILE}" ]; then
    awk '{print $2}' ${TMPFILE} | xargs rm
    git commit -a -m "Remove encrypted files"
    fi
    rm -rf .git-crypt
    git commit -a -m "Remove git-crypt"
    git commit -m "Remove git-crypt (in particular configuration related to key ${KEY_TO_REMOVE})" .git-crypt
    rm -rf .git/git-crypt

    # Re-initialize git crypt
    @@ -147,6 +150,7 @@ for keyfilename in `ls $CURRENT_DIR/.git-crypt/keys/default/0/*gpg`; do
    basename=`basename $keyfilename`
    key=${basename%.*}
    if [[ $key == $KEY_FINGERPRINT ]]; then
    echo "ignoring key ${KEY_FINGERPRINT} to be removed"
    continue;
    fi
    git crypt add-gpg-user $key
    @@ -162,7 +166,7 @@ cd $TMPDIR/$BASENAME
    for i in `awk '{print $2}' ${TMPFILE}`; do
    git add $i
    done
    git commit -a -m "New encrypted files"
    git commit -m "New encrypted files" || true
    popd

    git crypt lock
  9. Sebastien Varrette revised this gist Sep 18, 2019. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -30,7 +30,7 @@
    # amended to work on Mac OS and with cosmetic changes for a more convenient interface in
    # https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    #################
    set -eo pipefail
    # set -eo pipefail

    KEY_TO_REMOVE=
    KEY_FINGERPRINT=
    @@ -119,6 +119,10 @@ CURRENT_DIR=$(git rev-parse --show-toplevel)
    BASENAME=$(basename `pwd`)
    TMPFILE=list-encrypted-files.txt

    cat <<EOF
    TMPDIR=${TMPDIR}
    CURRENT_DIR=${CURRENT_DIR}
    EOF
    # Unlock the directory, we need to copy encrypted versions of the files
    git crypt unlock

  10. Sebastien Varrette revised this gist Sep 18, 2019. 1 changed file with 106 additions and 27 deletions.
    133 changes: 106 additions & 27 deletions remove-gpg-user.sh
    100644 → 100755
    Original file line number Diff line number Diff line change
    @@ -9,48 +9,127 @@
    # Removing a user will prevent them from reading future changes but they will
    # still have a copy of the data up to the point of their removal.
    #
    # Use:
    # ./remove-gpg-user.sh [FULL_GPG_FINGERPRINT]
    # Usage: see 'remove-gpg-user.sh -h'
    # remove-gpg-user.sh -l : list GPG keys configured within git-crypt for the current directory
    # remove-gpg-user.sh -r <FULL-GPG-FINGERPRINT> : remove specified key from git-crypt configuration
    # Ex: remove-gpg-user.sh -r 3BC18383F838C0B815B961480F8CAF5467D
    #
    # E.g.:
    # ./remove-gpg-user.sh 3BC18383F838C0B815B961480F8CAF5467D
    # Typical workflow (assuming the script is placed in ~/bin/) :
    #
    # cd /path/to/protected/repo
    # git checkout -b git-crypt-remove
    # ~/bin/$(basename $0) -l # List configured GPG keys
    # ~/bin/$(basename $0) -r <KEYID>
    #
    # The script will create multiple commits to your repo. Feel free to squash them
    # all down to one.
    #
    # Based on https://github.com/AGWA/git-crypt/issues/47#issuecomment-212734882
    #
    # GIST source https://gist.github.com/glogiotatidis/e0ab45ed5575a9d7973390dace0552b0
    # amended to work on Mac OS in https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    #
    set -e

    if [ -z "$1" ]
    then
    echo " Use:"
    echo " ./remove-gpg-user.sh [FULL_GPG_FINGERPRINT]"
    echo ""
    echo " E.g.:"
    echo " ./remove-gpg-user.sh 3BC18383F838C0B815B961480F8CAF5467D"
    exit;
    fi

    TMPDIR=`mktemp -d`
    CURRENT_DIR=`git rev-parse --show-toplevel`
    # amended to work on Mac OS and with cosmetic changes for a more convenient interface in
    # https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    #################
    set -eo pipefail

    KEY_TO_REMOVE=
    KEY_FINGERPRINT=
    CMD_PREFIX=

    ###############
    print_error_and_exit() { echo -e "*** ERROR *** $*\n Usage: see '$(basename $0) -h'"; exit 1; }
    really_continue() {
    echo -n -e "/!\\ WARNING: $*\n Are you sure you want to continue? [Y|n]"
    read ans
    case $ans in
    n*|N*) exit 1;;
    esac
    }
    print_usage() {
    cat <<EOF
    Remove a given GPG key from a git-crypt enabled repository.
    Usage:
    $(basename $0) -l : list GPG keys configured within git-crypt
    $(basename $0) [-n] -r <FULL-GPG-FINGERPRINT> : remove key from git-crypt configuration
    Typical workflow:
    cd /path/to/protected/repo
    git checkout -b git-crypt-remove
    ~/bin/$(basename $0) -l # List configured GPG keys
    ~/bin/$(basename $0) -r <KEYID>
    You can check the full, 64-bit (8-byte) key ID for a key within your keyring with
    gpg -k [email | pattern]
    gpg -k --with-colons [email | pattern | id] | awk -F: '/^pub:/ { print $5 }'
    EOF
    }

    ###
    # Print info for a given key from your keyring
    ##
    print_key_info() {
    [ -z "$1" ] && print_error_and_exit "[$FUNCNAME] missing text argument"
    local key=$1
    local gpgid=$(gpg --list-keys --with-colons $key | awk -F: '/^pub:/ { print $5 }')
    local fpr=$(gpg -k --with-colons $key | awk -F: '/^fpr:/ { print $10; exit; }') # Only first fpr
    echo "==== Key Fingerprint: ${fpr} ==="
    echo "==== Long GPG ID: ${gpgid}"
    gpg --list-key "$key" || print_error_and_exit "Couldn't find info about $key"
    export KEY_FINGERPRINT=$fpr
    }

    ###
    # List GPG keys configured for protecting this repository
    ##
    list_git_crypt_keys() {
    for f in .git-crypt/keys/default/0/*.gpg; do
    # key="$(basename "${f}" .gpg)"
    print_key_info $(basename "${f}" .gpg)
    # gpgid=$(gpg --list-keys --with-colons $key | awk -F: '/^pub:/ { print $5 }')
    # echo "==== Key Fingerprint: ${key} ==="
    # echo "==== Long GPG ID: ${gpgid}"
    # gpg --list-key "$key" || print_error_and_exit "Couldn't find info about $key"
    done
    }

    ##### Let's go #####
    # Check for options
    while [ $# -ge 1 ]; do
    case $1 in
    -h | --help) print_usage; exit 0;;
    -l | --list) list_git_crypt_keys; exit 0;;
    -r | --remove) shift; KEY_TO_REMOVE=$1;;
    # -n | --dry-run) CMD_PREFIX=echo ;;
    esac
    shift
    done

    [ -z "${KEY_TO_REMOVE}" ] && print_error_and_exit "No key to remove has been indicated"

    print_key_info "${KEY_TO_REMOVE}"
    [ -z "${KEY_FINGERPRINT}" ] && print_error_and_exit "Unable to retrieve key fingerprint"
    really_continue "About to remove the GPG Key ID ${KEY_TO_REMOVE} from Git-crypt configuration"

    # Below code adapted from @glogiotatidis - https://gist.github.com/glogiotatidis/e0ab45ed5575a9d7973390dace0552b0
    TMPDIR=$(mktemp -d)
    CURRENT_DIR=$(git rev-parse --show-toplevel)
    BASENAME=$(basename `pwd`)
    TMPFILE=list-encrypted-files.txt

    # Unlock the directory, we need to copy encrypted versions of the files
    git crypt unlock

    # Work on copy.
    cp -rp `pwd` $TMPDIR

    cp -rp $(pwd) $TMPDIR

    pushd $TMPDIR/$BASENAME

    # Remove encrypted files and git-crypt
    git crypt status | grep -v "not encrypted" > encrypted-files
    awk '{print $2}' encrypted-files | xargs rm
    git crypt status | grep -v "not encrypted" > ${TMPFILE}
    awk '{print $2}' ${TMPFILE} | xargs rm
    git commit -a -m "Remove encrypted files"
    rm -rf .git-crypt
    git commit -a -m "Remove git-crypt"
    @@ -63,20 +142,20 @@ git crypt init
    for keyfilename in `ls $CURRENT_DIR/.git-crypt/keys/default/0/*gpg`; do
    basename=`basename $keyfilename`
    key=${basename%.*}
    if [[ $key == $1 ]]; then
    if [[ $key == $KEY_FINGERPRINT ]]; then
    continue;
    fi
    git crypt add-gpg-user $key
    done

    cd $CURRENT_DIR
    for i in `awk '{print $2}' ${TMPDIR}/${BASENAME}/encrypted-files`; do
    for i in `awk '{print $2}' ${TMPDIR}/${BASENAME}/${TMPFILE}`; do
    #cp -rp --parents $i $TMPDIR/$BASENAME;
    #gcp -rp --parents $i $TMPDIR/$BASENAME;
    rsync -rp -R $i $TMPDIR/$BASENAME;
    done
    cd $TMPDIR/$BASENAME
    for i in `awk '{print $2}' encrypted-files`; do
    for i in `awk '{print $2}' ${TMPFILE}`; do
    git add $i
    done
    git commit -a -m "New encrypted files"
  11. Sebastien Varrette revised this gist Sep 17, 2019. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -20,6 +20,8 @@
    #
    # Based on https://github.com/AGWA/git-crypt/issues/47#issuecomment-212734882
    #
    # GIST source https://gist.github.com/glogiotatidis/e0ab45ed5575a9d7973390dace0552b0
    # amended to work on Mac OS in https://gist.github.com/Falkor/7b29f16f5f79404fe41476be0d992783
    #
    set -e

    @@ -69,6 +71,7 @@ done

    cd $CURRENT_DIR
    for i in `awk '{print $2}' ${TMPDIR}/${BASENAME}/encrypted-files`; do
    #cp -rp --parents $i $TMPDIR/$BASENAME;
    #gcp -rp --parents $i $TMPDIR/$BASENAME;
    rsync -rp -R $i $TMPDIR/$BASENAME;
    done
  12. Sebastien Varrette revised this gist Sep 17, 2019. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -69,7 +69,9 @@ done

    cd $CURRENT_DIR
    for i in `awk '{print $2}' ${TMPDIR}/${BASENAME}/encrypted-files`; do
    cp -rp --parents $i $TMPDIR/$BASENAME;
    #cp -rp --parents $i $TMPDIR/$BASENAME;
    #gcp -rp --parents $i $TMPDIR/$BASENAME;
    rsync -rp -R $i $TMPDIR/$BASENAME;
    done
    cd $TMPDIR/$BASENAME
    for i in `awk '{print $2}' encrypted-files`; do
  13. Sebastien Varrette revised this gist Sep 17, 2019. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -69,7 +69,8 @@ done

    cd $CURRENT_DIR
    for i in `awk '{print $2}' ${TMPDIR}/${BASENAME}/encrypted-files`; do
    cp -rp --parents $i $TMPDIR/$BASENAME;
    #gcp -rp --parents $i $TMPDIR/$BASENAME;
    rsync -rp -R $i $TMPDIR/$BASENAME;
    done
    cd $TMPDIR/$BASENAME
    for i in `awk '{print $2}' encrypted-files`; do
  14. @glogiotatidis glogiotatidis revised this gist May 24, 2016. No changes.
  15. @glogiotatidis glogiotatidis created this gist May 24, 2016.
    84 changes: 84 additions & 0 deletions remove-gpg-user.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    #!/bin/bash
    #
    # Script to remove GPG key from git-crypt
    #
    # It will re-initialize git-crypt for the repository and re-add all keys except
    # the one requested for removal.
    #
    # Note: You still need to change all your secrets to fully protect yourself.
    # Removing a user will prevent them from reading future changes but they will
    # still have a copy of the data up to the point of their removal.
    #
    # Use:
    # ./remove-gpg-user.sh [FULL_GPG_FINGERPRINT]
    #
    # E.g.:
    # ./remove-gpg-user.sh 3BC18383F838C0B815B961480F8CAF5467D
    #
    # The script will create multiple commits to your repo. Feel free to squash them
    # all down to one.
    #
    # Based on https://github.com/AGWA/git-crypt/issues/47#issuecomment-212734882
    #
    #
    set -e

    if [ -z "$1" ]
    then
    echo " Use:"
    echo " ./remove-gpg-user.sh [FULL_GPG_FINGERPRINT]"
    echo ""
    echo " E.g.:"
    echo " ./remove-gpg-user.sh 3BC18383F838C0B815B961480F8CAF5467D"
    exit;
    fi

    TMPDIR=`mktemp -d`
    CURRENT_DIR=`git rev-parse --show-toplevel`
    BASENAME=$(basename `pwd`)

    # Unlock the directory, we need to copy encrypted versions of the files
    git crypt unlock

    # Work on copy.
    cp -rp `pwd` $TMPDIR


    pushd $TMPDIR/$BASENAME

    # Remove encrypted files and git-crypt
    git crypt status | grep -v "not encrypted" > encrypted-files
    awk '{print $2}' encrypted-files | xargs rm
    git commit -a -m "Remove encrypted files"
    rm -rf .git-crypt
    git commit -a -m "Remove git-crypt"
    rm -rf .git/git-crypt

    # Re-initialize git crypt
    git crypt init

    # Add existing users, except the
    for keyfilename in `ls $CURRENT_DIR/.git-crypt/keys/default/0/*gpg`; do
    basename=`basename $keyfilename`
    key=${basename%.*}
    if [[ $key == $1 ]]; then
    continue;
    fi
    git crypt add-gpg-user $key
    done

    cd $CURRENT_DIR
    for i in `awk '{print $2}' ${TMPDIR}/${BASENAME}/encrypted-files`; do
    cp -rp --parents $i $TMPDIR/$BASENAME;
    done
    cd $TMPDIR/$BASENAME
    for i in `awk '{print $2}' encrypted-files`; do
    git add $i
    done
    git commit -a -m "New encrypted files"
    popd

    git crypt lock
    git pull $TMPDIR/$BASENAME

    rm -rf $TMPDIR