I want all users to cryptographically sign their contributions to a git repository. Commits, tags, merges, everything.
Supposing this process is flawed and somebody accidentally or on purpose manages to sneak a change into the repository which has not been signed. How can I detect this situation?
(Also, how do I properly specify "everything must be signed"? I was surprised to learn that merges can be signed separately from commits. What else is there?)
Based on spraff's answer and based on some experimentation into the git log format options, I've come up with the following script for finding unsigned commits. Install this on your PATH as a file named git-unsigned and you can invoke it as git unsigned or git-unsigned:
#!/bin/bash
set -e
function main() {
if [ "$1" == "-h" -o "$1" == "--help" ]; then
echo "usage: git-unsigned [-h|--help] [options]" >&2
echo "Show long refs for all unsigned/unverified git commits in the current tree." >&2
echo " -h, --help Display this usage guide." >&2
echo " options Options to be passed to the invocation of git log." >&2
return 1
fi
git log --pretty='format:%H|%aN|%s|%G?' $@ | awk -F '|' '{ if($4 != "G"){print $1;} }'
}
if [[ ${BASH_SOURCE[0]} == $0 ]]; then
main $@
fi
In my case, I found one commit where I wasn't prudent and didn't sign my commit:
575274a81b63d231f20e524b65030d96682fc646
Unfortunately, the solution to this is basically to amend the commit and sign it, which will be rewriting Git history and this is bad™.
The best thing to do is to use this tool as an audit tool to look at these commits, and upon examining the commit, nothing suspicious is found in git show 575274a81b63d231f20e524b65030d96682fc646.
I believe, though I am not certain, that if one were to rewrite this commit and to force push it, that the signatures of other commits would be either stripped or rendered invalid, so I think that we are still in the green on this, but I'd like to find the time and test it.
This guy wrote a script which will find unsigned commits in a repository.
#!/bin/sh
#
# Validate signatures on each and every commit within the given range
##
# if a ref is provided, append range spec to include all children
chkafter="${1+$1..}"
# note: bash users may instead use $'\t'; the echo statement below is a more
# portable option
t=$( echo '\t' )
# Check every commit after chkafter (or all commits if chkafter was not
# provided) for a trusted signature, listing invalid commits. %G? will output
# "G" if the signature is trusted.
git log --pretty="format:%H$t%aN$t%s$t%G?" "${chkafter:-HEAD}" \
| grep -v "${t}G$"
# grep will exit with a non-zero status if no matches are found, which we
# consider a success, so invert it
[ $? -gt 0 ]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With