I’ve already written about the Git Tag Object and made a passing reference to signed tags.
Git doesn’t make any checks about whether the name and email you enter into a git config file really is you, so it’s trivial make a check-in that looks like it’s been made by someone else. But, if you have some form of GPG installed, you can cryptographically sign a tag object (not a lightweight tag) than can be verified as being created by you.
Since a tag object references a commit, which in turn references another commit, and so on, a tag verifies a whole tree of commits. Changing any of the commits, or the tag, would mean new objects would be created that would break this tree. So by signing a tag, which points to a commit, a whole section of the code history is being validated by someone. And if you trust that person, and you trust his public key, you can verify that the tag was created by that person.
To create a signed tag, just pass the
-s flag instead of the
git tag -s -m"tagging version 1.0" v1.0
This will create a signed tag object called v1.0 with the passed commit message and it will use the signing identity of the committer (if there is a key for that). The documentation for
git-config states that you can set a key for
user.signingkey that will be used by default to sign commits, but I’ve found that I don’t need to do this as the correct key is used based on the
user.email that I am using. A prompt will come up asking you for your key’s passphrase.
If you want to use a particular signing identity when tagging then use then use:
git tag -u <key-id> -m"tagging version 1.0" v1.0
-u <key-id> specifies the key to use.
Also, as with commit messages, if you leave out the message an editor will be brought up for you to enter the tag message.
The signed tag object is only slightly different from the unsigned tag object in that it has a PGP signature block. To verify the signature use the
-v flag of the tag command
git tag -v v1.0
and if you have the correct public key for the user in your GPG Keychain it will let you know if the signature is valid or not.
In my earlier post I also mentioned that a tag object does not have to point at a commit; it can point to any other git object. In this way, you can also tag individual files or trees or even other tags if you are paranoid enough to want to. But this does nothing more than putting a name to a tag, or a commit. It establishes nothing more than responsibility - not a guarantee of quality nor of the origin of the work.